• ベストアンサー

sprintf の使い方について

C 言語の超初心者につき,おろかな質問をお許しください。 sprintf 関数について char str[40]; sprintf(str, "hogehoge %d", hoge_int); という文法はよく目にするのですが char *str; sprintf(str, "hogehoge %d", hoge_int); という文法はあまり見たことがありません。 両方ともちゃんと動くのですが,後者は文法的に正しいのでしょうか? char str[40] とした場合でも char *str とした場合でも, str は文字列の最初の文字のアドレスを表すんだったと思うんですが。 違いが分からず,混乱しています。 初心者につき,間抜けな質問をしているかもしれませんが,ご教授くださると幸いです。

質問者が選んだベストアンサー

  • ベストアンサー
  • DVD-RW
  • ベストアンサー率36% (195/541)
回答No.1

C言語はかなりご無沙汰の経験者です。用語とかも記憶の隅っこです。 char str[40]; こちらはstrに40byte分の静的な記憶領域が確保されています。 char *str; こちらはstrと言う名前のポインター変数を用意しただけで、実際の領域が与えられていません。 sprintf(str, "hogehoge %d", hoge_int); とする前に、strに確保された領域のアドレスを渡してあげなければいけません。(malloc関数?で動的な記憶領域を確保したり、ほかの静的な記憶領域のアドレスをポインターに渡します。)

k1220011_2005
質問者

お礼

ご回答くださり,ありがとうございます。

その他の回答 (1)

noname#22058
noname#22058
回答No.2

後者が正しく動いているように見えるのは、 「たまたま」です。 sprintfの第1引数に指定する領域は、 結合後の文字列の内容を確保できるだけの 大きさを持っていなければなりません。 後者の場合、どこか大事な領域を破壊しているかもしれません。

k1220011_2005
質問者

お礼

ご回答くださり,ありがとうございます。 > どこか大事な領域を破壊しているかもしれません。 ポインタを使っているときには,もっと思慮深くならないといけないようですね。 大変なことにならないようにも,注意深く,ポインタを使いたいです。 モヤモヤとしていた疑問が解消しました。 ありがとうございました。

関連するQ&A

  • sprintf

    文字列に1文字を結合したいんだけど、 例えば  char str[] = "xy";  char c = 'z'; があって、2つを結合する場合、 #include <iostream.h> main(){  char str[] = "xy";  char c = 'z';  char buf[2];  buf[0] = c;  buf[1] = 0;  strcat(str, buf);  cout << str; } でもいいけど、もっと簡単にする方法があったら教えてください。  char str[] = "xy";  char c = 'z';  sprintf(str, "%s%c\0", str, c);  cout << str; イメージ的にこうだけど、失敗しました。

  • sprintfを用いたフォーマット文字列攻撃

    sprintfを用いたフォーマット文字列攻撃に関する質問です。 main文の中で --------------------- int main(void){ char str[50]; sprintf(str,"%s"); puts(str); } --------------------- を実行すると(null)で帰ってきます。 しかし関数呼び出しを行うと結果が変わってきます。 --------------------- void f(){ char str[50]; sprintf(str,"%s"); puts(str); } int main(void){ f(); } --------------------- これを実行すると" ・L "のような文字化けしたものに変わりました。 sprintf(str,"%s%s");と記述することによって" ・L (null) "と、本来呼び出される箇所のものが格納されています。 なぜ関数呼び出しにすると変なところを参照してしまうのか(第3引数があると勘違いしてしまうのか)教えてください。 また、これによりどのような悪影響があるのか教えてください。 自分はプログラマが意図しない箇所を参照するため攻撃者のプログラムアドレスを格納してしまう恐れがあると考えています。

  • sprintfの使用方法に関して質問させていただきます。

    sprintfの使用方法に関して質問させていただきます。 sprintfを使用して、 文字と数字を取り扱う場合、 以下の例にもありますように、 %dと%sを使用したりしますが、 (ex) char test[256]; char num[] = "1234567"; char pg[] = "program"; int i386 = sprintf(buf,"%s%d",pg,num); 例えば、 以下のように、 上記例で、 pgが文字と数字が混在している場合と言うのは、 spintfはどう書き直せば正解なものなのでしょうか? char test[256]; char num[] = "1234567"; char pg[] = "http://image.blog/test001.gif"; アドバイスいただけますとありがたい次第です。 宜しくお願い致します。

  • sprintfに同じ変数は使えるか

    int sprintf( char *buffer, const char *format [, argument] ... ); 第1引数と第3引数以降に同じ変数を使えますか? memcpy()のように、同じ変数を使えない場合があるのか知りたいです。

  • sprintfのような関数を自作する

    表題のようにsprintfのような関数を自作することはできますか? 行いたいのは、例えば、 void TestKansu(AnsiString str) { //str文字列を処理 } という関数を用意したとしてこれを使うには AnsiString str; str.sprintf("TestMessage %d" , tes); TestKansu(str); としなくてはいけないと思いますが、もっと簡潔に TestKansu("TestMessage %d" , tes); とできるような関数を自作することは可能ですか? C++です。 宜しくお願いいたします。

  • sprintf 初歩的な質問

    お世話になっております。 最近独学でC言語の勉強を始めたのですが型の違う値の代入に関して わからないことがあり質問します。 ■やりたいこと■ char型dataの値を2で割った余りを char型ansの[0]から順番に格納してく。 (2の補数を取るためにこのような処理を 考えています(10進を24ビット2進へ変換したい)) ■コード■ #include<stdio.h> #include<stdlib.h> #include<string.h> #include<windows.h> int main(){ char data[256]="9"; int y; int i; char ans[25]; char* p_ans = ans; y=atoi(data); for(i=0;i<24;i++){ sprintf(ans[i], "%d",y%2); //←エラー y = y/2; } } ■質問■ 上記ソースの中のエラー部分をどのように記述していいのか わかりませんでした。初心者的な発想でポインタを使う方法はと思い sprintf(*(p_ans+i),"%d",y%2); というような記述も試してみましたが駄目でした。 この部分をどのように書いたらいいか詳しい方、教えていただけると 助かります。以上、よろしくお願いします。

  • sprintf()の使用方法

    先日から仕事で別の人が作ったソースを見ることになりました。 文字列連結を繰り返す処理でこんなコードが書いてありました。 char str[4096]; for(;;) {      /* 具体的な条件などは忘れました */ sprintf(str, "%s%s", str, var1);   /* 一応、var1はstrに対して十分小さな文字列。*/                      /* 繰り返しが終了するまで溢れることはないのですが */ } strcatなどを知らない人が作ったのでしょう。 一応、目的は達しているし、動いているみたいだからいいと言えばいいのかもしれないですが、なんか気持ち悪い。 こういうコードで何か問題はないのでしょうか?

  • sprintf関数について教えて下さい。

    sprintf関数について教えて下さい。 #include <stdio.h> int main(void) { int i; char ns[20][6]; for (i = 0; i < 20; i++) sprintf(ns[i], "No.%02d", i + 1); for (i = 0; i < 2; i++) printf("%s\n", ns[i]); return 0; } 上のプログラムでは結果が No.01 No.02 (中略) No.19 No.20 ですが、sprintf関数内の書式指定を"No.%02d\n"に変更した場合、 結果が No.01 No.02 (中略) No.19 No.20 No.02 No.03 (中略) No.19 No.20 No.03 No.04 (中略) No.19 No.20 (中略) No.19 No.20 No.20 になります。 どうしてこのようなことが起きてしまうのか自分では説明できません。 sprintf関数の説明も読んで納得はしたのですが 上のようになることがわかりません。 長々と書いてしまいましたが よろしくお願い致します。

  • int型変数をchar型変数に格納する方法

    int型数値をchar型変数に格納したいのですが、 sprintf()とatoi()を用いてやりましたが、 うまくいきません。 考えたコードを下記します。 int get_y(){ int y=2005; return y; } int main(){ char year; char str[5]; //intをcharに変換して格納している sprintf(str,"%d",get_y()); //数値として代入 year=atoi(str); //yearには2005が格納されていない! cout<<year<<endl; char ans; //このchar型変数に数値を代入する。 ans=year; cout<<ans<<endl; return 0; } お手数をお掛けしますが、 よろしくお願い致します。

  • [python] で packの方法を教えてください

    pythonで、バイナリファイルを扱おうと思います。 固定長の変数に、文字列と整数を代入する予定です。 環境は、Linuxのコマンドラインで使用します。 ---------------------------------- C言語で書くと、次のように成ります。 char[32] str; int [8] a; str = "test hoge"; a = 123; sprintf ("%32s%08d", str, a); //バイナリデータとして扱う ---------------------------------- 上記のように、文字列や数値をバイナリデータにしたいと思います。 最終的には、バイナリデータ・ファイルを生成します。 この場合、packを使えば出来そうですが、例題がなかなか見つからず困っています。 何か良い方法を知りませんか。 よろしくお願いします。 m(_ _)m

専門家に質問してみよう