• ベストアンサー

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

  • HTMC
  • お礼率85% (17/20)

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

  • ベストアンサー
  • Wr5
  • ベストアンサー率53% (2177/4070)
回答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% (2126/6286)
回答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

  • 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; } お手数をお掛けしますが、 よろしくお願い致します。

  • C言語のsprintfに相当するJAVAのメソッドは何か

    C言語ではデータを編集してメモリに出力する関数sprintfがある。 char rec[100] ; int i=1, j =2, k =3 ; sprintf(rec, "%3d %3d %3d", i, j, k ) と書くと、変数i,j,kの値が編集されてrecに入る。 このsprintfに相当するJAVAのメソッドはあるか。

    • ベストアンサー
    • Java
  • 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に代入する方法

    適当なアドレスをprintfで表示し、その値をintに代入するのが目的です。 #include <iostream> using namespace std; main(){ char buf[20]; char **pp; char *p = "\0"; int i; pp = &p; printf("%lu\n", pp); sprintf(buf, "%lu\n", pp); i = atoi(buf); printf("%lu\n", i); } とりあえずできていますが、 pp = &p;以降の処理で、bufを使ったり非推奨?のatoi()を使っています。 pp = &p;以降の処理でもっとよい方法はないでしょうか?

  • 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 は文字列の最初の文字のアドレスを表すんだったと思うんですが。 違いが分からず,混乱しています。 初心者につき,間抜けな質問をしているかもしれませんが,ご教授くださると幸いです。

  • アドレスをint変数に代入する方法

    printfで表示したアドレス値を、int変数に代入するのが目的です。 #include <iostream> using namespace std; main(){ char buf[20]; char *(*pp)[2]; char *p[2]; int i; pp = &p; printf("%lu\n", pp); // i = (int)(&pp); sprintf(buf, "%lu\n", pp);//// i = atoi(buf);//// printf("%lu\n", i); } とりあえずできていますが、 pp = &p;以降の処理で、bufを使ったり非推奨?のatoi()を使っています。 pp = &p;以降の処理でもっとよい方法はないでしょうか? また、このソースは不正なことをやっていないでしょうか? 必要な初期化をやってない、などということはありませんか?

  • char型・int型を相互変換させるプログラミング

    今、C++で2つのPC間で数値データの送受信を出来るようにしようと思い、実際にデータを飛ばせるところまで来たのですが、送れるデータの型はchar型のみであるとのこと。 ですので、intの値を一旦charにして送り、送った先でまたintにしたらいいかなと考えてプログラミングしました。 簡単にできると思ったのですが、上手くいきません・・・。プログラムのどの部分が間違っているのでしょうか? 一人では、これ以上悩んでも好転しないので、皆さんのご指導をお願いします 以下プログラム抜粋、このプログラムでは型変換がおこなわれているかの確認ができればいいので、それのみでプログラミングしています =================================================== #include <stdio.h> #include <stdlib.h> #include <string> #include <iostream> int main() { int a=123; char *b=new char; int c=1; //変換部分 *b=(char)a; std::cout<<"int→char>>>"<< c << "\n"; //逆変換部分 d=atoi(c); std::cout<<"char→int>>>"<< d << "\n"; } ======================================================

  • Cの文字列関連の質問です。よろしくお願いします。

    Cの文字列関連の質問です。よろしくお願いします。 『読み込んだ文字列がナル文字を含めて15文字以下であれば、その文字列をそのまま格納し、そうでない場合、読み込んだ文字列の先頭14文字とナル文字を格納する』 という条件を満たすプログラムを作成しました。 #include <stdlib.h> #include <string.h> #include <stdio.h> int main(void) { int num; char (*p)[15]; printf("文字列の個数: "); scanf("%d", &num); p = (char (*)[15])malloc(num * 15); if (p == NULL) puts("記憶域の確保に失敗"); else { int i; char tmp[100]; /* 書込み */ for (i = 0; i < num; i++) { printf("p[%d]: ", i); scanf("%s", tmp); sprintf(p[i], "%.14s", tmp); } /* 表示 */ for (i = 0; i < num; i++) printf("p[%d]: %s\n", i, p[i]); free(p); } return 0; } この場合は、ちゃんと条件を満たした結果が出ました。 ここで24行目の『sprintf(p[i], "%.14s", tmp);』を『strncpy(p[i], tmp, 14);』に変更する明らかに結果がおかしくなります。 strncpyを使った方法に変更する場合、どのように修正を行えばいいのでしょうか? 長々と書いてしまいましたが、よろしくお願い致します。

  • 初歩的な質問ですが教えてください。

    Cのあるプログラム中で、“他の実行ファイル”を用いた処理を行なう方法を 教えていただけないでしょうか。ただし、“他の実行ファイル”のソースファイルはありません。 例えば、aとbの二つの整数を渡して足し算する実行形式のファイルPlus.exeがあったとき、あるプログラム“test.c”の中で“Plus.exe”を用いて aとbの和Cを計算する方法を教えてください。 #include <stdio.h> int main(int argc, char *argv[]) { int a, b, c; a=atoi(argv[1]); b=atoi(argv[2]);   /* ここで c = a+b の計算をPlus.exeで行ないたいのですが・・・ */ printf("sum = %d\n", c); }

  • C言語の初歩的な質問

    質問1----------------------------------------- #include<stdio.h> int main() {  int a;  char b[10];  for(int i = 0;i < 2;i++){   scanf("%d",&a);   printf("整数%d\n",a);  }  scanf("%s",b);  printf("文字列%s\n",b); } /* この際に、例えばabと入力すると結果が 整数-858993460 整数-858993460 文字列ab となり整数入力を無視して進められるのはなぜでしょうか? */ 質問2----------------------------------------- #include<stdio.h> void func(int**); int main() {  int *p;  func(&p);  printf("%d",*p); } void func(int **pp) {  int n = 10;  *pp = &n; } /* func関数のnはスコープからはずれて変数の寿命がなくなるはずなのにprintfで表示されるのはなぜでしょうか? */ ---------------------------------------------- C言語は一冊の本とネットの入門サイトをかじった程度の理解です。