як створити умовну точку зупинки за допомогою std :: string


82

Припустимо, у мене є така функція:

std::string Func1(std::string myString)
{
   //do some string processing 
   std::string newString = Func2(myString)
   return newString;  
}

як встановити умовний розрив, коли newStringмає певне значення? (без зміни джерела)

встановлення умови newString == "my value"

точки роботи не працювали, точки зупинки вимкнено з помилкою "перевантажений оператор не знайдений"


1
Не знаю, чи це намір, але ваш код зламаний. Func1 повертає void, але ви повертаєте std :: string. Func2 не відображається, але він, мабуть, не повертає std :: string, крім того, ви використовуєте оператор == (дорівнює), а не = (призначення).
falstro

поганий приклад з моєї сторони, виправлений, але суть полягала в тому, щоб проілюструвати проблему отримання умовних точок зупинку за допомогою std :: string для роботи
Елі,

Відповіді:


49

Деякі пошуки не змогли знайти жодного способу для цього. Запропоновані альтернативи - поставити тест у свій код і додати стандартну точку зупинки:

if (myStr == "xyz")
{
    // Set breakpoint here
}

Або побудувати свій тест на основі порівняння індивідуальних персонажів. Навіть дивитися на окремі символи в рядку трохи хитромудро; у Visual Studio 2005 мені довелося скористатися змінними-членами, такими як

myStr._Bx._Buf[0] == 'x' && myStr._Bx._Buf[1] == 'y' && myStr._Bx._Buf[2] == 'z'

Жоден із цих підходів не є задовільним. Ми повинні мати кращий доступ до повсюдної функції Стандартної бібліотеки.


+1. Я просто писав подібну відповідь. Єдиний спосіб, яким я знаю це, - це зазирнути всередину реалізації. Зверніть увагу, що для std :: string це може стати досить складним через оптимізацію короткого рядка.
Адріан Маккарті

Це має проблему, яка myStr._Bx._Bufдійсна лише тоді, коли myStr._Mysize < _BUF_SIZE. В іншому випадку вам потрібно використовуватиmyStr._Bx._Ptr
RunHolt

3
Ця відповідь більше не актуальна для нових Visual Studio. strcmp(myStr._Mypair._Myval2._Bx._Ptr, "xyz") == 0просто працює
Майкл Векслер

85

У Visual Studio 2010/2012 є набагато простіший спосіб.

Щоб досягти того, що ви шукаєте в ANSI, використовуйте це:

strcmp(newString._Bx._Ptr,"my value")==0 

А в unicode (якщо newString був unicode) використовуйте це:

wcscmp(newString._Bx._Ptr, L"my value")==0 

Ви можете зробити щось більше, ніж просто порівняти, ви можете прочитати більше про це тут:

http://blogs.msdn.com/b/habibh/archive/2009/07/07/new-visual-studio-debugger-2010-feature-for-cc-developers-using-string-functions-in-conditional- точки зупинку.aspx


Мені подобається ця відповідь, вона спрацювала для мене (за деякими винятками, коли пам’ять була недоступна).
зірвано

23
Як припускають інші коментарі, доступ newString._Bx._Ptrможе не працювати для коротких рядків. У моєму випадку я отримав "Спробу читати або писати захищену пам'ять". Для коротких рядків (16 символів або менше?), newString._Bx._BufСхоже, містять символи.
vvnurmi

1
Чи це має працювати також у VS2015? Тому що, здається, це не спрацьовує на мій кінець ...
BmyGuest

1
Я не знаю про VS, але для gdb ви можете написати strcmp(newString.c_str(), "my_value") == 0. Можливо, знадобиться більше обчислень, але це легше запам'ятати.
Jounathaen

1
@Jounathaen Не працює у VS, на жаль: "Цей вираз має побічні ефекти і не буде оцінений."
letmaik

19

У VS2017 ви можете це зробити

strcmp(newString._Mypair._Myval2._Bx._Buf,"myvalue")==0

3
Це насправді залежить від Windows SDK, який ви використовуєте. Я використовую 10.1.15068 з Visual Studio 2015, і це працює, тоді як string._Bx._Buf або string._Bx._Ptr - ні.
Стюарт Уелч

15

У VS2017 мені вдалося встановити умову як:

strcmp(&newString[0], "my value") == 0

1
Працює також у VS2019, і набагато очевидніший та читабельніший та легший для запам’ятовування, ніж усі інші відповіді.
Скотт Хатчінсон,

8

Хоча мені довелося обійти це, використовуючи щось подібне до відповіді Бреда (плюс використання DebugBreak (), щоб зламати прямо з коду), іноді редагування / перекомпіляція / повторний запуск трохи коду або занадто трудомісткий, або просто неможливий .

На щастя, мабуть, можливо заглянути в фактичних членів класу std :: string. Один з способів згадується тут - і хоча він волає VS2010 конкретно, ви можете отримати доступ до окремих чарсу вручну в більш ранніх версіях. Отже, якщо ви використовуєте 2010 рік, ви можете просто скористатися приємними strcmp()функціями тощо ( більше інформації) , але якщо ви схожі на мене і все ще маєте 2008 рік або раніше, ви можете придумати обшаровану, жахливу, але функціональну альтернативу встановивши умовну точку зупинки приблизно так:

strVar._Bx._Ptr[0] == 'a' && strVar._Bx._Ptr[1] == 'b' &&
   strVar._Bx._Ptr[2] == 'c'

розбити, якщо перші три символи в strVar є "abc". Звичайно, ви можете продовжувати з додатковими символами. Некрасиво .. але це заощадило мені трохи часу зараз.



3

@OBWANDO (майже) має рішення , але, як справедливо зазначають кілька коментарів, фактичний буфер залежить від розміру рядка; Я бачу, що 16 є порогом. Попереднє додавання перевірки розміру до strcmp у відповідному буфері працює.

newString._Mysize < 16 && strcmp(newString._Bx._Buf, "test value") == 0

або

newString._Mysize >= 16 && strcmp(newString._Bx._Ptr, "ultra super long test value") == 0

Це наслідок невеликої оптимізації буфера. Огляд високого рівня тут blogs.msmvps.com/gdicanio/2016/11/17/… . Більш детально
Aerom Xundes

Так, це правильне рішення. Як вже зазначалося, невелика оптимізація рядків не виділяє пам'ять, якщо довжина рядка менше 16
Серж Вайнсток

2

Намагався використовувати strcmpв gdb8.1under ubuntu18.04, але це не працює:

(ins)(gdb) p strcmp("a", "b")
$20 = (int (*)(const char *, const char *)) 0x7ffff5179d60 <__strcmp_ssse3>

Відповідно до цієї відповіді , strcmpє спеціальним IFUNC , можна встановити умову, як це:

condition 1 __strcmp_ssse3(camera->_name.c_str(), "ping")==0

Це досить потворно, не хочу робити це вдруге.

Ця відповідь дає набагато краще рішення, в ньому використовується std :: string :: compare :

condition 1 camera->_name.compare("ping") == 0


1

Порівняння рядків працює краще, ніж порівняння символів

strcmp(name._Mypair._Myval2._Bx._Buf, "foo")==0

Це працює, але дуже незручно у використанні та спричиняє помилки.

name._Mypair._Myval2._Bx._Buf[0] == 'f' && 
name._Mypair._Myval2._Bx._Buf[1] == '0' && 
name._Mypair._Myval2._Bx._Buf[2] == '0'

1

Ви можете перетворити його в рядок змінного струму, використовуючи c_str()приблизно так:

$_streq(myStr.c_str(), "foo")

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.