2016-11-22 11 views
0

プロジェクトを見て、次のコードを見つけて、sprintfが何をしているのか理解できず、誰かが私を助けてくれることを望んでいたそれを理解する。問題「char * str + int」のsprintfを理解する

char storage[64]; 
int loc = 0; 
int size = 35; 

sprintf(storage+(loc),"A"); //Don't know what this does 
loc+=1; 
sprintf(storage+(loc),"%i", size); //Don't know what this does 
loc+=4; 
sprintf(storage+(loc), "%i", start); //Don't know what this does 

start += size; 
loc += 3; 

コードは、後にはsprintfに関する私がオンラインに見てきた別の部分では、次の

string value; 
int actVal; 
int index = 0; 
for(int j = index+1; j < index+4; j++) 
{ 
    value += storage[j]; 
} 
istringstream iss; 
iss.str(value); 
iss >> actVal; //Don't understand how this now contains size 

例は、上記のコードは可能であったことをカバーしたことがないんが、プログラムはうまく実行されます。私は "+ loc"がこのインスタンスのストレージにどのような影響を与え、どのように値を保存/保存するかを理解することはできません。どんな助けもありがとう。

+1

短い答えは任意のポインタに整数を加えたもので、その多くの要素を進めたポインタを返します。基本的にsprintfに 'loc'空間をバッファに印字するように指示します。 – vu1p3n0x

+1

同じコードベースが 'ostringstream'ではなく' istringstream'を使用しているので、 'sprintf'を使用する必要はありません。 – PaulMcKenzie

+0

'sprintf'はCライブラリ関数です。バッファオーバーフローの機会を複数作成する点を除いて、現代のC++コードではほとんど使用されていません。終わりのないバグの源泉以外の目的はほとんどありません。 –

答えて

0

醜いコード!それに関わらず、最初の部分については、storage+(loc) == &storage[loc]です。第二部のために

sprintf(&storage[0],"A"); 
sprintf(&storage[1],"%i", size); 
sprintf(&storage[5], "%i", start); 

、と仮定すると、我々は上記の"A35\0<unknown_value>1234\0"を持って、我々が得る:あなたはstart = 1234、または長い形式で仮定して、文字列"A35\0<unknown_value>1234\0"で終わるだから今value = "35"

value += '3'; 
value += '5'; 
value += '\0'; 
value += '<unknown_value>'; // This might technically be undefined behaviour 

。 [1]

iss.str(value); 
iss >> actVal; 

これは、入力ストリームに文字列をオンにし、整数、"35"を表す第1の文字列を読み出し、基本的にactVal = atoi(value.c_str());米国を与え、整数に変換します。

最後に、according to this pageはい、初期化されていない( "不定値"は公式な用語です)配列要素は未定義の動作であるため、避けるべきです。

[1]は明らかに良い結果ではないであるので、value350359の間になってしまう可能性があり、通常の実装では、<unknown_value>は、ASCII数字が含まれていることができることを理論的に256分の10可能性があることに注意してくださいなぜ未定義の振る舞いを無視してはならないのかです。

0

関数sprintf()は、結果がstdoutに出力されない点を除いて、printf()のように機能しますが、文字列変数に格納されます。

https://linux.die.net/man/3/sprintf

あなたがLinux上でない場合でも、その関数は、それをWindows、Macや他の動物も、ほとんど同様の異なるプラットフォーム間である:私はあなたが慎重にsprintf() manページを読むことをお勧め。つまり、あなたが提示したこのコードは不必要に複雑なようです。

最初の部分

は、のように書くことができます: - 等しくない類似した - しかし、結果については

sprintf(storage,"A %i %i", size, start); 

が、その後、再び、それはすべて正確に、元のプログラマが保持するため、この記憶領域を意図したものに依存します。 Kenが指摘したように、このコードからそのままの未定義のバイトと振る舞いがあります。標準から

0

:文字列 へ

int sprintf (char * str, const char * format, ...);

書き込みフォーマットされたデータは、フォーマットはprintf関数で使用された場合に印刷されるのと同じテキストを持つ文字列を変換し、代わりに印刷されているの、コンテンツは、strが指すバッファにC文字列として格納されます。

sprintf(storage+(loc),"A");

storageと呼ばれるバッファに "A" を書き込みます。 storage+(loc)はポインタ演算です。あなたは書いている文字配列のインデックスを指定しています。従って、storage = "A"。ここで

sprintf(storage+(loc),"%i", size);

あなたは[1]ストレージにsizeを書いています。今すぐstorage = "A35\0"loc = 1など。 storage = "A35\0<garbage><value of start>\0"

actValの

あなたの最終的な値:これは今ループのサイズ

ザ・はstorage[5]を通じてstorage[1]を通過し、storageの内容を使用してvalueを構築含まれているかを理解しないでください。 valueには、文字列"35\0<garbage>"が含まれ、iss.str(value)には、"35\0"まで削除されます。

iss >> actVal

あなたはstd::cinに遭遇した場合、それは同じ概念です。整数値を含む最初の文字列がactValに書き込まれます。

関連する問題