2017-08-23 40 views
1

に引数を渡すながらcharへの文字列を書く:to.Howeverに従ってszNameでszFmtを組み合わせながら、私はこれを実行すると、私は、szBufでszFmtを結合しようとしている私は次のコードを持っている文字列

char szBuf[256] = ""; 
std::string szFmt = "You have recieved %s item." 
string szName = "Fork"; 
snprintf(szBuf, sizeof(szBuf), szFmt.c_str(), szName); 

をwin10のコード、私はそのような奇妙な出力を得ています:

あなたはLアイテムを受け取りました。

そして、私はOSXエルキャピタンでコードを実行しようとすると、私は次のエラー

が可変引数機能throgh非自明なタイプ「文字列」のオブジェクトを渡すことはできません取得しています。 実行時に呼び出されます

だから何が問題なのですか?これをどのように解決できますか?

注:私はthisの質問をチェックしましたが、答えでは、彼らは直接 "フォーク"を渡しています。しかし、szNameとして渡すとうまくいきません。

+0

[ 'snprintf'の二番目の引数を使用すると、str機能を使用し、文字列にアクセスするには

](http://en.cppreference.com/w/c/io/fprintf)は、*宛先バッファ*のサイズである必要があります。あなたの場合は 'sizeof szBuf'でなければなりません。'std :: string'オブジェクトのサイズを取得すると、' std :: string'オブジェクトの実際のサイズを取得します。これには、それに含まれる文字列のサイズ( 'szFmt.length()' )。 –

+2

ここでCとC++のイディオムを混在させているので、問題が発生しています。 'sizeof(szFmt)'は文字列の長さを決して与えません。 'szFmt.length()'になります。しかし、実際には、単にsnprintfを削除してストリームを使用してください。 –

+0

@Someprogrammerdude指摘してくれてありがとう、私はそれを修正しましたが、あなたが推測するように、問題は残っています。 – onurcanbektas

答えて

5

コメント(ostringstream)で解決策がより詳しく説明されましたが、さらなる教育的価値については、ここで直面する問題を解決します。

Varargs(printfファミリのファンクションで可変数の引数を受け入れることができるメカニズム)は、他のものと同じように厳密に型チェックされていません。この場合、snprintfは文字列にchar*が必要ですが、stringオブジェクトであるszNameを渡しています。だから、あなたにもその上の.c_str()を呼び出す必要があります:

snprintf(szBuf, sizeof(szBuf), szFmt.c_str(), szName.c_str()); 
1

それはより多くのタイプセーフなCから継承しprintf機能よりもだ、特に以来、物事を単純化しますstd::ostringstreamを使用するだけでなく、それはとして、すべての標準タイプを扱うことができるので、出力オペレータ<<の適切なオーバーロードは、カスタムクラスに対しても非常に簡単に使用できます。

std::ostringstreamで覚えておくべき重要なことは、それだけでstd::coutのように、通常の出力ストリームである、とあなたがstd::coutを使用することができるならば、あなたもstd::ostringstream(またはその他の標準出力ストリーム)を使用することができるということです。

それを使用する方法については、今

std::ostringstream ostr; // Define the stream object 
ostr << "You have recieved " << szName << " item."; 

そして、それはそれについてです。

std::cout << "The output is " << ostr.str() << '\n'; 

そして、あなたはいくつかの理由でcharバッファにコピーしたい場合:

// Use `strncpy` to not overflow the destination buffer 
std::strncpy(szBuf, ostr.str().c_str(), sizeof szBuf - 1); 

// Remember that `strncpy` might not terminate the destination, so do it explicitly 
szBuf[sizeof szBuf - 1] = '\0'; 
関連する問題