• ベストアンサー

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); というような記述も試してみましたが駄目でした。 この部分をどのように書いたらいいか詳しい方、教えていただけると 助かります。以上、よろしくお願いします。

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

  • ベストアンサー
  • Wr5
  • ベストアンサー率53% (2173/4061)
回答No.1

> char型dataの値を2で割った余りを > char型ansの[0]から順番に格納してく。 「数値」として入れたいのでしょうか? 「数字」として入れたいのでしょうか? 「数値」と「数字」の違いについては以下のページを。 http://homepage3.nifty.com/mmgames/c_guide/04-01.html http://www.ipc.hokusei.ac.jp/~z00206/program/item/soft-variable.htm http://bugyo.tk/~harumak7/zick/program/c_lang/0402.htm 数値としてならば ans[i] = y%2; 数字としてならば ans[i] = '0' + y%2; でよろしいかと。(文字列として扱う場合、'\0'を忘れずに…) 意図的に文字列として扱いたいようなので… sprintf(&ans[i], "%d",y%2); でどうでしょうか?

HTMC
質問者

お礼

入れたいのは数字としてと考えていました。 数値としての代入と、数字としての代入ありがとうございました。 教えていただいた方法にて問題解決することが出来ました。 1点、数字としての方法で'0'+y%2とするとchar + int となると 思うのですがこのあたりが私にはまだよく理解できませんでした。。。 今後勉強してみようと思います。 --その他-- ネットで探してみると10ビットまでの変換プログラムがあり、 10のべき乗とループを組み合わせることで2進数を作る方式が ありましたが、これ以上はintの範囲を超えるため24ビットの 計算はcharの方がよいと考えています。

その他の回答 (2)

  • x415f484f
  • ベストアンサー率71% (57/80)
回答No.3

※ 既に回答が得られていますので、蛇足なのですが気になるので。 # この私のアドバイスにお礼は要りません。 ポインタはとても重要なのでもっと詳しく勉強されることをお薦めします。 # 私もうっかり似たようなミスをやってしまうのですが。 ポインタについて学習されているとは思いますが、よりいっそう 理解を深めることが望ましいと思われるので。 このサイトの「第10章 ポインタ」をご覧になるとわかり易いと 思います。 初心者のためのポイント学習C言語 http://www9.plala.or.jp/sgwr-t/ > sprintf(ans[i], "%d",y%2); //←エラー ans とした時は配列の(先頭の)ポインタですが ans[i] はポインタでは ありませんのでポインタを得るには &ans[i] とするべきです。 printf("%d", ans[i]); /* ans[i] に格納された値 */ printf("%p", &ans[i]); /* ポインタアドレス値 */ とすれば値が確認できます。 > sprintf(*(p_ans+i),"%d",y%2); *(p_ans+i) はポインタではありません p_ans+i がポインタとなります。 printf("%d", *(p_ans+i)); /* ポインタアドレスに格納された値 */ printf("%p", p_ans+i); /* ポインタアドレス値 */ とすれば値が確認できます。 慣れないうちはこのように printf で値を確認しながらデバッグすると よいかと思います。 VC++ などをお使いであればデバッグ実行でブレークポイントを設定 して値を確認しながら実行をすることが出来ます。

HTMC
質問者

お礼

返信不要とありましたがアドバイスをいただいたので お礼申し上げます。ちなみに私はVCではなくGCCでコンパイル しています。デバッグ方法も大変参考になりました。 No2.さんに聞いた内容について参考として挙げていただいた HPを勉強して解決することができました。とてもわかりやすい HPの紹介ありがとうございました。 配列を逆から入れていくという件に関して、 ■ソース 一部■ char inv[25]; char* p_inv=inv; for(i=0;i<24;i++){ sprintf(p_ans+i, "%d",y%2); *(p_inv+23-i) = *(p_ans+i); y = y/2; } 最初sprintfで代入すると\0が最後に入ることが わからず苦労しましたがほかの配列を用意して そこにポインタで値を入れることで解決できました。 おそらく無駄が多いと思いますのでご指摘など あれば幸いです。

  • asuncion
  • ベストアンサー率33% (2127/6289)
回答No.2

> sprintf(*(p_ans+i),"%d",y%2); p_ansを使いたい場合は、 sprintf(p_ans+i,"%d",y%2); です。

HTMC
質問者

お礼

ご回答ありがとうございました。 回答のp_ansはアドレスの値として扱われるんですね。 こういう書き方もあるというよい勉強になりました。 ありがとうございました。   ずうずうしいですがもう1点、今回2進数を作るということでこの「ans」にはいっている内容を ans => [0][1][2]....[23]\0  となっているところを ans => [23][22][21]......[0]\0  としたかったため、 sprintf(p_ans+(24-i),"%d",y%2); としたのですがまたもやエラーとなってしまいました。 この件に関してはこのページを見ずにもう少し考えて見ますが もし可能でしたらどうやるかを後で見れるようにアドバイス いただけるとさらにありがたいです。

関連するQ&A