質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

4回答

231閲覧

[C]入力と出力が噛み合わない。

wanwannyaan

総合スコア31

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2019/06/24 14:02

入力が次の形式で与えられます。

input

1データ型 データ数 データ1 データ2・・・

example1

1int 5 3 1252 20 58 10000

example2

1char 4 honma maji imiwakannne tasukete

このとき、プログラムでは与えられたデータ型の配列(要素数=データ数)を作成し、データを前から順番に配列に格納します。
この格納が上手くいっているかどうか、コメント(1)(2)の行でテストしたところ、データ型がint,charのどちらについても配列の先頭(添え字0)のみ正しく格納されており、他は0が入っているか滅茶苦茶な数字が入っているという状態でした。
いろいろ悩みましたがお手上げ状態なので、解決策(正しくデータを配列に格納する方法)を教えてください。

以下ソースコード

C

1#include <stdio.h> 2#include <string.h> 3#include <stdlib.h> 4 5void int_func(int items, char *s) { 6 int i; 7 int i_num[items]; 8 i_num[0] = atoi(strtok(s, " \0")); 9 for(i=1;i<items;i++){ 10 i_num[i] =atoi(strtok(NULL, " \0")); 11 } 12 for(i=0;i<items;i++){ 13 printf("%d\n",i_num[i]); /*(1)*/ 14 } 15} 16 17void char_func(int items, char *s) { 18 int i; 19 char *c[items]; 20 c[0] = strtok(s, " \0"); 21 for(i=1;i<items;i++){ 22 c[i] = strtok(NULL, " \0"); 23 } 24 for(i=0;i<items;i++){ 25 printf("%s\n",c[i]); /*(2)*/ 26 } 27} 28 29struct type_table { 30 char *type; 31 void (*func)(int, char*); 32} table[] = { 33 { "int", int_func }, 34 { "double", double_func }, 35 { "float", float_func }, 36 { "char", char_func }, 37 { NULL, NULL } 38}; 39 40 41int main(void){ 42 int items; 43 char buf[1024]; 44 char type[7]; 45 char value[1018]; 46 fgets(buf, sizeof(buf), stdin); 47 sscanf(buf,"%s %d %s",type, &items, value); 48 for(int i=0; table[i].type != NULL; i++) { 49 if(strcmp(table[i].type, type) == 0) { 50 table[i].func(items, value); 51 break; 52 } 53 } 54} 55

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答4

0

ベストアンサー

あまりちゃんと見ていませんが、sscanf の書式を次のようにすればどうなりますか?

C

1sscanf(buf,"%s%d %[^\n]", type, &items, value);

投稿2019/06/24 14:32

kazuma-s

総合スコア8224

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

wanwannyaan

2019/06/24 14:57

直りました ありがとうございます
kazuma-s

2019/06/24 14:59

なぜ直ったかを考えて、あるいは調べて、ここに書いてください。 調べても分からない時は、何を調べたのかを書いてください。
wanwannyaan

2019/06/24 15:06

scanfが空白文字で読み取りを終えてしまうとこに原因があったようですね。 今回の修正で改行コードが現れるまですべての文字を強制的に読み込むように命令しました。
guest

0

既に指摘があるように、

sscanf(buf,"%s %d %s",type, &items, value);

がダメです。 valueには、最初の文字列(空白で区切られた)しか入りません。

C

1 type = strtok(buf, " "); 2 items = atoi(strtok(NULL, " "));

のようにして、valueに相当するのは、そのまま、strtok(NULL, " ")で読み込ませるのもありかも知れません。(他の箇所の変更も必要ですが)

なお、" \0"\0 は不要です。文字列は必ず、\0で終わるため。

投稿2019/06/24 14:44

pepperleaf

総合スコア6383

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

wanwannyaan

2019/06/24 14:58

ありがとうございます。 \0の件修正しました。
guest

0

ある程度以上のコードを組む場合、VisualStudioとかEclipseとかのデバッグできる環境を整えましょう。
任意の行で実行を止め、変数のナカミが見れるようになります
そうすれば当てずっぽでコードを書かなくて済むようになります

投稿2019/06/24 14:07

y_waiwai

総合スコア87719

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

例えばint_func関数なのですが、

i_num[0] = atoi(strtok(s, " \0")); for(i=1;i<items;i++){ i_num[i] =atoi(strtok(NULL, " \0")); }

この処理の部分、どこが違うか分かりますか?
また、違う箇所はどのように処理が変わっているか分かりますでしょうか。

答えを載せるのは違うと思いましたので、自己解決へ至る為のヒントを載せさせて頂きました。
配列について、for文について、関数について。調べ方から学ぶと良いかもしれませんね。
「C言語 知りたい事 より詳しく」
の順で検索して調べていってみて下さい。
例としては「C言語 関数 とは」のような感じです。

難しいと感じて苦しいかもしれませんが、解けた時の喜びは大きいので頑張ってみて下さい。

投稿2019/06/24 14:17

marurunn

総合スコア702

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問