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

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

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

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

標準入力

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

Q&A

解決済

6回答

7544閲覧

指定の文字列を超えた入力がされた時、エラーと表示したい

Re0922

総合スコア6

C

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

標準入力

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

0グッド

0クリップ

投稿2020/04/29 03:14

編集2020/04/29 03:31

C言語で、指定の文字列を超えた入力がされた時、fgets関数を用いてエラーと表示したいです。
includeするのは<stdio.h>のみという条件です。

wikipediaでは、

char a[20];

if (fgets(a, 20, stdin) == NULL) {
// エラー処理
}

のように紹介されていますが、エラー処理のところに
printf("Error");として、20文字以上入力しても、エラーが表示されません。

よろしくお願いします。

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

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

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

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

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

guest

回答6

0

指定の文字列を超えた入力がされた時

fgets()では、指定した範囲を超えては入力が為されないので、関数としてはエラーにはなりません。
fgets()は入力データから改行が得られるかあるいは指定文字数に達するかまで取り込むだけ。指定文字数以上のデータが入力ストリームにあることは正常に想定される事態であってエラーではありません。

したがって、質問にいう「エラー」とは入力された文字列をあなたがエラーとみなすかどうかというだけの話なので、入力された文字列をあなたが検査して下さい。先頭から指定文字数まで一文字ずつ'\n'なのか、'\0'なのか、それともそれ以外なのかに応じて適切に処理すればわかるでしょう。文字数を数える必要もありません。

for(int i=0; i<20; i++){//0から19まで順に if(a[i]=='\n'){//好みならswitch文とかを使ってもいいけど //'\n'に出会ったということは「エラー」ではなかったということだから、ループを抜ければいい } if(a[i]=='\0'){ //'\n'に出会うこと無く文字列が終わったということは、入力に指定文字数以上あったということ。 } //それ以外だった }

投稿2020/04/29 04:27

thkana

総合スコア7629

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

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

0

majiponi さんの回答はいいアイデアですが、
fgets の引数の順序が間違っているのと、
エラーの場合のリカバリがないので、複数行の読み込みができません。

そこで、次のようなコードを書いてみました。

C

1#include <stdio.h> 2 3#define N 20 4 5int main(void) 6{ 7 char s[N]; 8 while (s[N-2] = '\0', fgets(s, N, stdin)) { 9 if (s[N-2] != '\0' && s[N-2] != '\n') { 10 puts("Error"); 11 int c; 12 while ((c = getchar()) != EOF && c != '\n') ; 13 } 14 else 15 fputs(s, stdout); 16 } 17}

投稿2020/04/29 13:01

kazuma-s

総合スコア8224

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

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

0

includeするのは<stdio.h>のみ

string.h がダメというのであれば, (20バイト限定の) strlen 相当を自作すれば良いのではないでしょうか.

課題の趣旨がその辺りにあるのかもしれませんし, そもそも課題を質問するのはダメでしょう.

投稿2020/04/29 03:33

編集2020/04/29 03:34
jimbe

総合スコア12632

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

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

0

C

1int fgetshortline(FILE* fp, char* buf, int n) 2{ 3 buf[n-2] = '\0'; 4 return fgets(fp, buf, n) && (!buf[n-2] || buf[n-2] == '\n'); 5} 6 7char buf[21]; 8if(!fgetshortline(stdin, buf, sizeof(buf))){ 9 /* too long, or io error */ 10}

動くかどうかは試してませんが、こんな感じでしょうか?

投稿2020/04/29 10:46

majiponi

総合スコア1720

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

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

0

ベストアンサー

18文字以下の入力の場合、入力した文字列の最後に\n(改行)と\0の2バイトが続きます。
strlen(a)は入力した文字数+改行文字の1です。

19文字以上の入力の場合、入力した文字列の先頭19文字の後、つまりa[19]\0が入ります。
strlen(a)は、19です。

なので、a[strlen(a)-1]\nかどうか調べればどちらか分かります。

20文字目以降の入力していない文字列は次の入力関数の実行で取得されます。

投稿2020/04/29 03:24

otn

総合スコア84505

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

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

Re0922

2020/04/29 03:28

丁寧な回答ありがとうございます。しかし、質問にも書きましたが、includeするのは<studio.h>のみなんですよね。読まれやすいように、編集しますね。すみません。 できればもう一度、回答お願いしたいです。
otn

2020/04/29 03:34

じゃあ、aの先頭から`0`が現れるまで調べて、その直前が'\n'かどうか見ればいいです。
otn

2020/04/29 04:34

もっと簡単にできるか。先頭から'\0'か'\n'かどちらかが現れるまで調べて、先に'\0'が出てきたら、19文字以上って事ですね。
Re0922

2020/04/29 04:35

char a[5]として、abcdと入力した場合、 a[0]にa、a[1]にb、a[2]にc、a[3]にd、a[4]に\0 が入ると思うですが、改行文字\nはどこに入るのでしょうか? よろしくお願いします。
otn

2020/04/29 04:37

a[4]に\nで、a[5]に\0 です。
Re0922

2020/04/29 04:56

ではabcdeと入力した場合、 a[4]、a[5]には、なにがはいるのでしょうか? 質問多くて申し訳ないです。 よろしくお願いします。
otn

2020/04/29 05:10

回答を読んでませんか? > 19文字以上の入力の場合、入力した文字列の先頭19文字の後、つまりa[19]に\0が入ります。 の19を4と読み替えてください。
Re0922

2020/04/29 12:26

助言のおかげで実装できました。 ありがとうございました。 以下に0~5文字以外(6文字以上)の入力がなされた時エラーと表示するコードを載せておきます。 char a[7]; int x,y; fgets(a, 7, stdin); for (x = 0; x < 7; x++) { //xは改行文字がある配列の添え字 if (a[x] == '\n') { break; } else { continue; } } for (y = 0; y < 7; y++) { //yは改行文字がある配列の添え字 if (a[y] == '\0') { break; } else { continue; } } if (y < x) { printf("error\n"); } else { printf("ok\n"); }
otn

2020/04/29 12:35

どちらか早く出た方だけ見れば良いので、1つのループの中にifを2つ入れれば良いです。'\0'は必ずあるので、回数での終了チェックも不要です。 for(x=0;;x++){ if(a[x]=='\0') { printf("error\n"); break; } else if(a[x]=='\n'){ printf("ok\n"); break; } }
guest

0

指定文字数以上入力された場合、文字列終端の'\0'がつかないので、そこらへんを見ればいいんじゃないかと。
strlen(a)が20以上のときにエラーを出しましょう

投稿2020/04/29 03:16

編集2020/04/29 03:18
y_waiwai

総合スコア87749

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

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

Re0922

2020/04/29 03:19

strlenを使うには、<string.h>を使わないといけないんですよね... <stdio.h>のみという条件の学校の課題ですので、よろしくお願いします。
y_waiwai

2020/04/29 03:20

それを質問に書こうよ。あとづけでいわれても なら、コードで文字列長を調べればいいかと。
Re0922

2020/04/29 03:23

質問の下の方に書いてます。わかりづらくてすみません。
episteme

2020/04/29 03:31

だったら オレオレstrlen をこしらえて呼べばいいじゃん。 int oreore_strlen(const char* str) { int n = 0; while ( *str++ != '\0' ) ++n; return n; }
otn

2020/04/29 04:37

> strlen(a)が20以上 これはあり得ないです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問