Как создать условную точку останова с помощью std::string
Предположим, у меня есть эта функция:
std::string Func1(std::string myString)
{
//do some string processing
std::string newString = Func2(myString)
return newString;
}
как установить условный перерыв, когда newString
имеет конкретное значение? (без изменения источника)
установка условия newString == "my value"
не работает точки останова были отключены с ошибкой "перегруженный оператор не найден"
12 ответов
Некоторым поискам не удалось найти какой-либо способ сделать это. Предлагаемые альтернативы - поместить тест в ваш код и добавить стандартную точку останова:
if (myStr == "xyz")
{
// Set breakpoint here
}
Или создать свой тест из сравнения отдельных персонажей. Даже смотреть на отдельные символы в строке немного рискованно; в Visual Studio 2005 мне пришлось копаться в переменных-членах, таких как
myStr._Bx._Buf[0] == 'x' && myStr._Bx._Buf[1] == 'y' && myStr._Bx._Buf[2] == 'z'
Ни один из этих подходов не является очень удовлетворительным. У нас должен быть лучший доступ к вездесущей функции Стандартной библиотеки.
В Visual Studio 2010/2012 есть гораздо более простой способ.
Чтобы выполнить то, что вы ищете в ANSI, используйте это:
strcmp(newString._Bx._Ptr,"my value")==0
И в Unicode (если newString был Unicode) используйте это:
wcscmp(newString._Bx._Ptr, L"my value")==0
Есть больше вещей, которые вы можете сделать, чем просто сравнение, вы можете прочитать об этом здесь:
В VS2017 я смог установить условие как:
strcmp(&newString[0], "my value") == 0
В VS2017 вы можете сделать
strcmp(newString._Mypair._Myval2._Bx._Buf,"myvalue")==0
VS2012:
Я просто использовал условие ниже, потому что newString._Bx._Ptr
(как в ответе OBWANDO) ссылается на незаконную память
strcmp( newString._Bx._Buf, "my value")==0
и это сработало...
Хотя мне приходилось обходить это, используя что-то похожее на ответ Брэда (плюс использование DebugBreak(), чтобы вырваться из кода), иногда редактирование / перекомпиляция / повторный запуск небольшого количества кода либо слишком трудоемки, либо просто невозможны,
К счастью, по-видимому, можно использовать настоящие члены класса std::string. Здесь упоминается об одном способе - и хотя он специально вызывает VS2010, вы все равно можете обращаться к отдельным символам вручную в более ранних версиях. Так что если вы используете 2010, вы можете просто использовать хороший strcmp()
функции и тому подобное ( больше информации), но если вы похожи на меня и у вас еще есть версия 2008 или более ранняя, вы можете придумать рваную, ужасную, но функциональную альтернативу, установив условную точку останова, например:
strVar._Bx._Ptr[0] == 'a' && strVar._Bx._Ptr[1] == 'b' &&
strVar._Bx._Ptr[2] == 'c'
сломать, если первые три символа в strVar - "abc". Вы можете продолжать идти с дополнительными символами, конечно. Ужасно... но это сэкономило мне немного времени.
У @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
Пытался использовать strcmp
в gdb8.1
под 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
Сравнение строк работает лучше, чем сравнение символов
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'
В VS2015 вы можете сделать
newstring[0]=='x' && newString[1]=='y' && newString[2]=='z'
Вы можете преобразовать его в строку переменного тока, используя c_str()
вот так:
$_streq(myStr.c_str(), "foo")
Чтобы установить условную точку останова в std ::string, вам необходимо установить ее на реальных внутренних членах std ::string. То, что вы видите в окне просмотра, упрощено.
Вы можете отобразить реальную структуру переменной в окне просмотра, используя
,!
суффикс. В вашем примере:
newString,!
Для MSVC 2015-2019 вы можете использовать:
Для строки длиной не более 15 символов:
(newString._Mypair._Myval2._Myres < 16) ?
strcmp(newString._Mypair._Myval2._Bx._Buf, "short") == 0 :
false
Для (даже исторически) более длинных строк:
(newString._Mypair._Myval2._Myres < 16) ? false :
strcmp(newString._Mypair._Myval2._Bx._Ptr, "My_test_str_value_longer_than_16_chars") == 0
Остерегаться:
- Имя переменной записывается дважды в каждом условии!
- Вам нужно все выражение в одной строке. Используйте версии для копирования и вставки, указанные ниже.
Универсальное условие требует, чтобы тестовое значение было дважды, а имя переменной - трижды:
(newString._Mypair._Myval2._Myres < 16) ?
strcmp(newString._Mypair._Myval2._Bx._Buf, "My_test_string") == 0 :
strcmp(newString._Mypair._Myval2._Bx._Ptr, "My_test_string") == 0
Примечания: используйте
wcscmp
вместо того
strcmp
если вы работаете с
std::wstring
.
Дополнительные сведения об оптимизации небольших строк в C++ https://vorbrodt.blog/2019/03/30/sso-of-stdstring/ включает образец кода для определения размера внутреннего буфера строки.
Все однострочные версии std: string и std ::wstring для удобства копирования и вставки:
(newString._Mypair._Myval2._Myres < 16) ? strcmp(newString._Mypair._Myval2._Bx._Buf, "short") == 0 : false
(newString._Mypair._Myval2._Myres < 16) ? false : strcmp(newString._Mypair._Myval2._Bx._Ptr, "My_test_str_value_longer_than_16_chars") == 0
(newString._Mypair._Myval2._Myres < 16) ? strcmp(newString._Mypair._Myval2._Bx._Buf, "My_test_string") == 0 : strcmp(newString._Mypair._Myval2._Bx._Ptr, "My_test_string") == 0
(newString._Mypair._Myval2._Myres < 16) ? wcscmp(newString._Mypair._Myval2._Bx._Buf, L"short") == 0 : false
(newString._Mypair._Myval2._Myres < 16) ? false : wcscmp(newString._Mypair._Myval2._Bx._Ptr, L"My_test_str_value_longer_than_16_chars") == 0
(newString._Mypair._Myval2._Myres < 16) ? wcscmp(newString._Mypair._Myval2._Bx._Buf, L"My_test_string") == 0 : wcscmp(newString._Mypair._Myval2._Bx._Ptr, L"My_test_string") == 0
Все вышеперечисленные образцы копирования / вставки протестированы на MSVC версии 16.9.10 и в программе для Windows 10.