🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
C

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

標準入力

標準入力(stdin)は、プログラムが標準的に用いるデータ入力元。リダイレクトしない限り、プログラムを起動した端末のキーボードが標準入力になります。UNIX系OSやC言語に実装されて普及した概念ですが、他のOSや言語も含めた総称としても使われます。

Q&A

解決済

3回答

811閲覧

c言語:標準入力の方法

zyunnsuke

総合スコア4

C

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

標準入力

標準入力(stdin)は、プログラムが標準的に用いるデータ入力元。リダイレクトしない限り、プログラムを起動した端末のキーボードが標準入力になります。UNIX系OSやC言語に実装されて普及した概念ですが、他のOSや言語も含めた総称としても使われます。

0グッド

0クリップ

投稿2021/02/13 07:52

すみません。標準入力についての質問です。
自然数Q、文字列str、自然数numが以下のような条件で与えられるとき、どのように受け取るのがきれいな形なのでしょうか?

Q        ///与えられたQの数だけ文字列strと自然数numが一行で渡される。 str_1 num_1 str_2 num_2 ・・・ str_Q num_Q

私はいつもfgetsで受け取り、その後空白を探索してその後にある文字をatoiでint型に直しています。
以下のようなコードです。

char str[1][1000],kazu1[1]; int i,j,Q,kazu; fgets(str[0], sizeof(str[0]), stdin); sscanf(str[0],"%d",&Q); ///先頭の自然数の取り出し for(i=0;i<Q;i++){ fgets(str[0],sizeof(str[0]),stdin);   ///str_n num_nの取り出し for(j=0;j<strlen(str[0]);j++){ if(str[0][j] == ' '){ kazu1[0] = str[0][j+1]; kazu = atoi(kazu1);

標準入力について調べてみてもあまり情報がなく、どうにもなりませんでした。

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

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

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

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

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

guest

回答3

0

きれいな方法というのが短いコードで書くこいうことなら
scanf()で一気に取ってしまうのが簡単だと思います

ただ入力間違いなどに対応できないので
安定して動くという意味では劣ります

C++

1#include <stdio.h> 2#include <stdlib.h> 3#include <string.h> 4 5struct data_set 6{ 7 char str[256]; 8 int num; 9}; 10 11int main(int argc, char** argv) 12{ 13 int Q; 14 struct data_set *data; 15 16 scanf("%d", &Q); 17 18 data = (struct data_set*)malloc(sizeof(data_set)*Q); 19 20 for(int i=0; i<Q; i++) 21 { 22 scanf("%s %d", data[i].str, &(data[i].num)); 23 } 24 25 for(int i=0; i<Q; i++) 26 { 27 printf("%s, %d\n", data[i].str, data[i].num); 28 } 29}

投稿2021/02/13 08:15

DaiGuard

総合スコア159

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

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

zyunnsuke

2021/02/13 10:12

なるほど、ありがとうございます。解決しました!
guest

0

ベストアンサー

標準入力って、単にOS側が渡してくる文字列、というだけです。特に「調べる」というほどのことはないと思いますが...
知っておくべきは
・標準入力はデフォルトではキーボード入力に割り当てられることが多い
・キーボードから入力する場合、入力はまずOS側で蓄積(バッファリング)され、Enterキーをトリガにまとめてアプリケーションに渡される。つまり、標準入力の生成はアプリケーションの外で行われる
・標準入力を取り込む関数の多くは、入力がない場合ブロック(関数から戻らない)する
ぐらいでしょうか。

「きれい」というのは、とても感覚的でなにが基準かわかりかねます。

sscanfを知っているのなら、空白を探すのは不要で(sscanfが内部でやってくれる)

C

1char str[1000];//変更 2for(i=0;i<Q;i++){ 3 char s[1000];//配列にするとか必要ならどうぞ 4 int num; 5 6 fgets(str,sizeof(str),stdin);   ///str_n num_nの取り出し 7 sscanf(str, "%s%d", s, &num); 8}

で十分な気もします。
scanf系の書式指定文字列で"%d"は文字列先頭の空白文字を読み飛ばしてから数値を取得する指示、
一方" "は空白文字を読み飛ばす、という指示
なので、結果として"%s%d"と"%s %d"はどちらも結果はかわりません。

あるいは、単純にscanfで

C

1for(i=0;i<Q;i++){ 2 char s[1000];//配列にするとか必要ならどうぞ 3 int num; 4 5 scanf("%999s%d", s, &num);//文字列に読み込む最大桁数は制限しておかないと、scanf警察が踏み込んできたりします。 6}

とか。

これら二つは、異常系を想定しないなら、動作は同様と言っていいでしょうが、文字列が長すぎたときや数字が入力されずに改行されたとき等の動作に違いがあります。
異常系を真面目に考えるなら、想定する異常を列挙します。一つ一つ想定した事態に対応していく毎に複雑さを増していく(=きれいでなくなる)ことになります。scanf系の関数は異常入力に対する対応がとても面倒なことも多いのでstrtolなどで変換することになるでしょう。atoiは変換の失敗を検出できないので異常対応がある場合は使えません。

以下余談ですが...
char str[1][1000],kazu1[1];
なにか特別な意図があるのかも知れませんが、一般に要素数1の配列を取ることは無駄です。配列である必然性がありません。引き続き領域を確保して、配列を拡張するような使い方をすることは皆無ではありませんが、この場合はそうではないでしょう。

あと、質問のコードは文字列は取得していないし数値の取得も間違っているようにおもいますがいかが。

投稿2021/02/13 09:34

thkana

総合スコア7703

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

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

zyunnsuke

2021/02/13 10:24

そうですよね。もう少し具体的な表現を心がけます。詳しい解説ありがとうございました。 動かしていたプログラムの一部を切り抜いたので、間違いが発生したものと思います。以後気を付けます。
guest

0

fgets+sscanfで良いのではないでしょうか。

ただし、sscanfの返り値は必ず確認しましょう。

投稿2021/02/13 08:56

otn

総合スコア85893

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

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

zyunnsuke

2021/02/13 09:36

fgets+sscanfも試してみたのですがその場合 文字列 str_n num_n と 文字列 str_n という形にしか出来なかったです。 文字列 str_n num_n から 文字列 str_n と  数  num_n 形にもできますか? すみません、かなり日本語が拙くなってしまいました。
otn

2021/02/13 09:41

ちょっと意味が読み取れません。 何をしたいのでしょうか?
zyunnsuke

2021/02/13 10:09

以前試した私のコードにミスがあり、 fgets(str,sizeof(str),stdin); sscanf(str,"%s%d",str_n,&num_n); ができないものだと思い込んでおりました。 慎重に試したところ無事解決しました。ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問