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 2009年

私の側の悪い例は修正されましたが、要点はstd :: stringを使用して条件付きブレークポイントを機能させる問題を説明することでした
Eli

回答:


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 2016

3
この回答は、新しいVisualStudioには関係ありません。strcmp(myStr._Mypair._Myval2._Bx._Ptr, "xyz") == 0うまくいく
Michael Veksler 2018

85

Visual Studio2010 / 2012にははるかに簡単な方法があります。

ANSIで探していることを達成するには、次を使用します。

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

そしてユニコード(newStringがユニコードの場合)ではこれを使用します:

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


私はこの答えが好きです、それは私のために働きました(メモリがアクセスできなかったいくつかの例外を除いて)。
2013年

23
他のコメントが示唆しているように、アクセスnewString._Bx._Ptrは短い文字列では機能しない可能性があります。私の場合、「保護されたメモリの読み取りまたは書き込みを試みました」というメッセージが表示されました。短い文字列(16文字以下?)の場合newString._Bx._Buf、文字を保持しているようです。
vvnurmi 2013

1
これはVS2015でも機能するはずですか?それは私の最後に動作していないようなので...
BmyGuest

1
VSについてはわかりませんが、gdbの場合はと書くことができますstrcmp(newString.c_str(), "my_value") == 0。内部でより多くの計算が必要になる場合がありますが、覚えるのは簡単です。
Jounathaen 2017

1
@Jounathaen残念ながら、VSでは機能しません:「この式には副作用があり、評価されません。」
letmaik

19

VS2017では次のことができます

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

3
実際には、使用しているWindowsSDKによって異なります。Visual Studio 2015で10.1.15068を使用していますが、これは機能しますが、string._Bx._Bufまたはstring._Bx._Ptrは機能しません。
スチュアートウェルチ

16

VS2017では、条件を次のように設定できました。

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

1
VS2019でも機能し、他のすべての回答よりもはるかにわかりやすく、読みやすく、覚えやすいです。
スコットハッチンソン

8

ブラッドの答えに似たものを使用してこれを回避する必要がありましたが(さらに、DebugBreak()を使用してコードから直接中断する)、コードの一部を編集/再コンパイル/再実行するのは時間がかかりすぎるか、まったく不可能な場合があります。

幸いなことに、std :: stringクラスの実際のメンバーに侵入することは明らかに可能です。ここでは1つの方法について説明します。彼は、VS2010を具体的に呼び出していますが、以前のバージョンでは、個々の文字に手動でアクセスできます。したがって、2010を使用している場合は、素敵なstrcmp()関数などを使用できます(詳細)が、私のように2008年以前を使用している場合は、不規則でひどいが機能的な代替手段を思い付くことができます。次のような条件付きのブレークポイントを設定します。

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

strVarの最初の3文字が「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/…。より多くの深さでここakrzemi1.wordpress.com/2014/04/14/common-optimizations
Aerom Xundes

はい、それは正しい解決策です。前述のように、文字列の長さが16未満の場合、小さい文字列の最適化ではメモリが割り当てられません
SergeWeinstock20年

2

使用しようとstrcmpしてgdb8.1ubuntu18.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'

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.