- ベストアンサー
数字のINPUT
数字を連続して、入力させようと思っています。 例 1,2,3 1 2 3 1, 2, 3, ⇒a[0]=1,a[1]=2,a[2]=3 上の例の様に、数字が出てくれば、その数字だけをint型で使えるようにint型の配列に格納したいです。 scanf()を使って%dでやるとバグが発生します。 gets()などでchar型でとった物をatoi()で変換する方法がよく分かりません。 私がやると、9までしか取り込めませんでした。 どなたか良い方法を教えてください。
- みんなの回答 (13)
- 専門家の回答
質問者が選んだベストアンサー
別の方法を考えてみました。 ---------------------------------------------------------------- #include <stdio.h> #include <string.h> void main() { int a[ 3 ]; char buf[ 256 ]; char *p; int count = 0; // 入力 gets( buf ); p = buf; while( *p != '\0' ) { // 数字がある所までシフトする p += strcspn( p, "1234567890" ); // 数値の抽出 sscanf( p, "%d", &a[ count++ ] ); // 数字以外の所までシフトする p += strspn( p, "1234567890" ); } // 表示 printf("%d %d %d\n", a[0], a[1], a[2] ); } ---------------------------------------------------------------- 関数の説明: strcspn( p, "1234567890" ) : 先頭から数字以外で構成される長さを取得する (例) "abc1234efg" なら "abc"の部分が該当するので結果は3である strspn( p, "1234567890" ) : 先頭から数字で構成される長さを取得する (例) "1234efg" なら "1234"の部分が該当するので結果は4である 今回のはどうでしょうか? またわからない箇所がありましたら 追って質問してくださいね(^_^) (PS:BLUEPIXYさん、調査報告ありがとうございました。)
その他の回答 (12)
- Trick--x--
- ベストアンサー率26% (19/72)
1.数字を入力させる 2.入力をヌルで終わる文字列(C言語で言う「文字列」)に入れる 3.strtok()で切り出す 4.atoi()で数値に変える 5.配列に代入する 以上!!
お礼
ありがとうございます。お手数を掛けました。
- BLUEPIXY
- ベストアンサー率50% (3003/5914)
#4補>やってみたのですが、何故か上手くいきません。 bcc32 だと似たような動作になってうまく動作しませんでした。 gccだとちゃんと動作しました。 bcc32 については、おそらくバグだと思います。
お礼
調べていただき、ありがとうございました。
- BlueStones
- ベストアンサー率65% (13/20)
BlueStonesです。 プログラム上は問題ないはずなので、 システム上の問題だと思うのですが。 なにぶん、そちらと同じ環境を整えることができませんでしたので、 確認することができないのですが。 詳しい原因箇所がわかりましたら ご連絡をいただけないでしょうか?
- BlueStones
- ベストアンサー率65% (13/20)
BlueStonesです。 お手数ですが、 あなたの開発環境は何でしょうか?
補足
学校でやっているのでよく分かりません。 RedHatLinux8.0だったと思います。 コンパイラは何を使っているのか不明です。
- mac_res
- ベストアンサー率36% (568/1571)
どうも仕様がはっきりしないので、自信なしですが、こういうことでしょうか? -- 8< -- 8< -- 8< -- 8< -- 8< -- 8< -- 8< -- 8< -- 8< -- 8< -- #include <stdio.h> #include <ctype.h> #define NMAX 100 int main(void) { int c; int sum, save, i, n; int a[NMAX]; printf("input numbers & ^D at last.\n"); n = 0; sum = 0; save = 0; while ((c = getchar()) != EOF) { if (isdigit(c)) { sum = sum * 10 + (c - '0'); save = 1; } else if (save) { printf("input[%d] = %d\n", n, sum); a[n++] = sum; sum = 0; save = 0; if (n >= NMAX) break; } } for (i = 0; i < n; i++) { printf("a[%d] = %d\n", i, a[i]); } return 0; }
- Trick--x--
- ベストアンサー率26% (19/72)
……えっと? ごめん、私には貴方の話が見えない。 #01への補足 ・12 3→1と2と3 と、私(#06)へのお礼 ・実際は50とかぐらいまで が整合するか? 前者の言を取るなら、数値はすべて一桁になるし、後者の言を取るなら前者は12と3か123にならなければおかしい……よね? 真坂、12は1と2 だけど 1.2は12 として読む…なんて不思議仕様じゃないでしょう? 一度話を整理してくれんか
お礼
質問しつつ、自分でもプログラムをいじっている内にいろいろと仕様の変更がありました。 すいません。 12,3は12と3です。数字が繋がっていればそれは一つの数字としてみようと思っています。数字以外の文字全ては区切り文字として扱う予定です。最悪、", . "ぐらいは区切り文字として認識させるつもりです。 #1の補足は誤りでした。ごめんなさい。
- Trick--x--
- ベストアンサー率26% (19/72)
0-9の数値を取り込むのですよね? char fgetc(FILE*) で一文字取得できます。(標準入力はstdinよ) ただし、これは「文字列」では無く「文字」なので、atoi()には渡せないと思います。 これを解決する方法は複数考えられます。 1.「文字」を「文字列」にする 2.「文字」用のatoiを作る。 1.「文字」chを「文字列」szに変換する方法 char ch,sz[2]; // 中略 sz[0] = ch; sz[1] = '\0'; ……うん、スマートじゃないね。 2.「文字」用のatoi的関数を作る方法 int ctoi(char ch) { switch((int)ch) { case '0': return 0; // 以下略 } } main(){ // 略 if(isalnum(ch)) a[i] = ctoi(ch); // 略 }
お礼
回答ありがとうございます。 私がやると、0~9までの一文字でしか出来なかったと言うだけで、 実際は50とかぐらいまでは入れます。 あと、数字もそれと同じく3つではなく、もっと多くとります。
- nofutureforyou
- ベストアンサー率9% (25/277)
(1)パーサージェネレーターを使う。 (2)色々な入力に対応するみたいなめんどくさいことことしない。 のどちらかがいいのでは。
お礼
回答ありがとうございます 1)は使った事ないのでわかりません。 2)は、そういう仕様にしろとの事なので出来ません。
- BlueStones
- ベストアンサー率65% (13/20)
atoi()は使っていませんが、こんなのはどうでしょうか。 #include <stdio.h> void main() { int a[ 3 ]; char buf[ 256 ]; int count = 0; int ret; // 入力 gets( buf ); // 初期読み込み ret = sscanf( buf, "%d%[^\0]", a, buf ); // 文字列がまだ残っているなら処理する while( 1 < ret && count < 3 ) { // 数値の抽出 ret = sscanf( buf, "%*[^0-9]%d%[^\0]", &a[ ++count ], buf ); } // 表示 printf("%d %d %d\n", a[0], a[1], a[2] ); } ---------------------------------------------------------------- 説明: まず、入力を文字列として取得します。 それをsscanf()で処理します。 sscanf():文字列変数から入力を読み取るタイプのscanf()です ここで大事なのが、書式フォーマットの部分です。 まず、%dで数字部分を取り出してa[0]に代入します。 そして、%[^\0]で残りの文字列をbufに代入します。 %[^\0]:'\0'以外の文字からなる文字列を取得 retには代入に成功した数が入るので、 数字だけ代入されたなら1が 文字列が残っていてそれがbufに代入されていたら2が代入されます。 もしここで2が代入されていたらwhile文の中を処理します。 while文の中のsscanf()では 書式フォーマットに%*[^0-9]が追加していることに注意してください %*[^0-9]:0~9以外の文字からなる文字列を取得 ('*'指定はそれを取得するだけで代入はしないという指定です) これで後はretが1以下になるまで処理を繰り返せば 配列に数字が代入されていきます。 説明が長くなってしまいましたが、わかりましたでしょうか^_^; 実際に打ち込んでみて確認すると良いと思います。 では、がんばってください♪
お礼
そんな方法があったんですね! ご丁寧な説明ありがとうございます。
補足
やってみたのですが、何故か上手くいきません。 で、確かめてみると、retは14になっていたり、bufは変化していなかったり・・・ 4,5,6と入力すると、4としか表示されません。 どうしてなんでしょうか?コピーして使ってみたんですが・・・・
- mac_res
- ベストアンサー率36% (568/1571)
#include <stdio.h> #include <stdlib.h> int main(void) { char buf[BUFSIZ], x[BUFSIZ], y[BUFSIZ], z[BUFSIZ]; int a[3], i; while (1) { printf("数値を3個入力 >> "); if (fgets(buf, BUFSIZ, stdin) == NULL) { return 0; } sscanf(buf, "%[0-9]%*[^0-9]%[0-9]%*[^0-9]%[0-9]", x, y, z); a[0] = atoi(x); a[1] = atoi(y); a[2] = atoi(z); for (i = 0; i < 3; i++) { printf("a[%d]=%d\n", i, a[i]); } } return 0; }
お礼
回答ありがとうございます。 質問の仕方が多少おかしかったかもしれませんが、 数字の入力は3個に限らずたくさん入力(30ぐらいまでかな?)させる予定です。
- 1
- 2
お礼
回答ありがとうございます。 実行できました。ありがとうございました。