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

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

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

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

Q&A

解決済

3回答

3721閲覧

C言語の構造体に対する標準入力

Miso___

総合スコア13

C

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

0グッド

0クリップ

投稿2020/06/01 06:58

c言語の標準入力と構造体に関する質問です。
例えばトランプのカードなどを入力する際に入力が"S3"や"D10"などで与えられるとして、これを構造体Cardの配列に保存していきたいです。
入力が一つの時は下記のようなコードでうまくいっています。

C

1#include "stdio.h" 2#include "stdlib.h" 3 4typedef struct Card Card; 5struct Card{char mark;int num;}; 6 7int main(){ 8 Card x[100]; 9#入力は例えば"S3"など 10 scanf("%c%d",&x[0].mark,&x[0].num); 11 printf("%c %d",x[0].mark,x[0].num); 12 return 0; 13}

これをn枚入力に拡張したコードを実行すると思ったように動作してくれません。
(入力は初めカード数nを入力してその後n枚分H3 K6...などを入力しています。
ex:
5
H4 C9 S4 D2 C3
)

C

1#include "stdio.h" 2#include "stdlib.h" 3typedef struct Card Card; 4struct Card{char mark;int num;}; 5 6int main(){ 7 int n,i; 8 Card x[100]; 9 10 scanf("%d",&n);#カード数n 11 for(i=0;i<=n;i++){ 12 scanf("%c%d",&x[i].mark,&x[i].num); 13 } 14 for(i=0;i<=n;i++){ 15 printf("%c %d",x[i].mark,x[i].num); 16 } 17 18 return 0; 19}

コードのミスや改善法などを教えていただければ幸いです。よろしくお願いします。

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

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

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

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

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

guest

回答3

0

ベストアンサー

scanf"%d""%s" などは先行する空白(スペース、タブ、改行など)を読み飛ばして
くれるので想定通りの入力ができますが、"%c" だけは空白の読み飛ばし機能がないので、
想定通りでない入力になることがよくあります。
" %c" のように直前にスペースを指定して 0個以上の連続する空白を読み飛ばしてから
1文字読み込むようにしてください。
scanf では "\n"" " と全く同じ機能であり、通常は使用しません。
はまる例としても次のものがあります。

C

1 printf("a: "); scanf("%d\n", &a); 2 printf("b: "); scanf("%d\n", &b);

キーボードから入力する場合、プロンプトの a: が出て、123 Enter と入力しても次の
プロンプト b: は出てきません。"\n" が空白でない文字が出てくるまで待ってしまうからです。

投稿2020/06/01 09:07

kazuma-s

総合スコア8224

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

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

Miso___

2020/06/01 09:19

補足まで頂いてありがとうございます、大変勉強になりました。 お陰様で解決することができました!ありがとうございました!
guest

0

以下の修正で期待通りにはなりました。

c

1scanf("%d",&n); 23scanf("%d\n",&n);

投稿2020/06/01 07:09

ttyp03

総合スコア17000

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

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

Miso___

2020/06/01 09:20

お陰様で解決することができました、ありがとうございます!
thkana

2020/06/01 12:00

そのパターンは今回「だけ」はいいけど、 #include <stdio.h> int main(void) { int a,b; printf("Enter..\n"); scanf("%d\n", &a); scanf("%d\n", &b); printf("%d %d\n", a, b); return 0; } なんてやってハマっているのをしばしば見かけるから止めたほうがいいと思う。
thkana

2020/06/01 12:02

って、kazuma-sさんが書いてたか。
ttyp03

2020/06/01 13:22

thkanaさん この手の処理なんて毎度決まったフォーマットがあるわけじゃないので、別に今回「だけ」でもいいと思いますけどね。 まあ何がダメでどうすればいいかを試す能力は鍛える必要はありますが。 もっとも他の回答にあるようにscanfははまるだけなのでgetsを使ってもらいたいですが。
thkana

2020/06/01 22:00

なぜscanfが嫌らしいかと言うと、本当は知ってなきゃいけないことをすっ飛ばして初心者に「お約束」だけで処理させようとするからで、そうするとデータとパターンがアンマッチしてハマるんじゃないですか。だったら、ハマりやすいパターンをわざわざ教えて「何がダメでどうすればいいかを試す能力は鍛え」てやるのは、ちょっとイジワルですよね。 で、そこでgetsお薦めですか? 標準から外されちゃいましたけど。
ttyp03

2020/06/01 23:53

随分食い下がりますねw 日常的にscanfを使いたい、scanfマスターになりたい、という人ならキッチリお勉強すればよいでしょうけど、この手の学校の課題みたいなやつはscanfを勉強しているわけじゃないですよね? そこに時間をかける必要はない、と個人的には思います。 仕事で使うということも私の場合は一切ありませんし、全然重要視していないのですよ。 thkanaさんがscanf大好きでお勧めしたい人なら意見が対立するのは仕方ないので、あとは質問者さんがどう受け止めるかだけじゃないですかね? getsが標準から外されたかどうかはしりませんが、getsでもfgetsでもgets_sでもまあなんでもいいですよ。「gets系」と書けばよかったですかね。
guest

0

そもそも文字列の入力はscanfでやってはいけません。
fgetsで1行取得してそこから分解させて、代入していきましょう

投稿2020/06/01 07:01

y_waiwai

総合スコア88042

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

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

Miso___

2020/06/01 09:20

fgetsをあまり使ったことがなかったため勉強になります、ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問