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

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

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

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

Q&A

解決済

2回答

1447閲覧

ungetcについて

user012

総合スコア11

C

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

0グッド

0クリップ

投稿2020/11/01 16:14

ungetc(c,stdio);の説明で、読み込んだ文字をストリームに1文字戻す。とあるのですが意味が分かりません。
便利な点の説明で、文字列を分解する際に、判定用の文字を1度読み込んだ後、
もう1度ストリームに戻してから改めて処理できる為、便利なのです。とあるのですが理解できません。
ungetcについて教えてください。

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

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

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

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

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

vann_2921

2020/11/01 16:20

ストリームは分かりますか?
user012

2020/11/01 16:25

キーボード等から得た文字であってますか?
vann_2921

2020/11/01 16:46

ちょっと違いますね。 説明が少し難しいのですが、いつでも文字が読み込める状態の入れ物のこと入力ストリームといいます。 そのストリームに対して「何文字くれ」という命令をして文字列を取得することができます。 ungetcはストリームに「1文字返すわ」という関数です。 すでに回答がついていますのでotnさんの回答を参考にしてください。
user012

2020/11/01 16:54

とするとgetchar()はキーボードから入力された文字を入力ストリームに入れるってことであってますか?
vann_2921

2020/11/01 17:04

getcharは既定のストリーム(標準入力ストリーム)があってそのストリームから1文字読み取るのだと思います。キーボードからの入力はまず標準入力ストリームに格納されるわけです。 違うかもしれません。
user012

2020/11/02 08:50

なるほど、理解できました!
user012

2020/11/02 09:00

stdin についても聞いていいですか? 説明で特に何も指定が無い場合キーボードからの標準入力を受け取ることができる標準ストリームです。とあるのですが c = getchar()で入力ストリームからとってきてるのでstdinって書くってことですか?
vann_2921

2020/11/03 01:48

stdinは標準入力ストリームのことだと思いますが、 「入力ストリームからとってきてるのでstdinって書くってことですか? 」 ここの意味が分かりません。 何か例を示してもらえますか? 実際に書いたらどうなるんでしょう?
user012

2020/11/03 02:04

ungetcの引数の定義があいまいでして勘違いをしていました 1つ目の引数が戻したい文字、2つ目が戻す場所の指定と。 ungetc(c ,stdin); cが戻したい文字で、stdinは標準入力ストリームに戻す。 と理解したのですがあってますか?
vann_2921

2020/11/03 02:11

使い方としてはあっています。 しかし、取ってきた場所に返さないといけないという決まりはないです。 どこに返すかはプログラムを書く人が決めることなので返す場所があっているかどうかは書いた人にしかわからないです。
guest

回答2

0

関数 getchar だけを使って、
scanf("%d", &num) と同等の機能を持つ関数 get_num と、
scanf("%s", str) と同等の機能を持つ関数 get_str を作ろうとすると
関数 ungetc が必要になります。

C

1#include <stdio.h> // getchar, ungetc, printf 2#include <ctype.h> // isspace, isdigit 3 4int get_num(int *n) 5{ 6 int c, val = 0, neg = 0; 7 while (isspace(c = getchar())) ; 8 if (c == '+') c = getchar(); 9 else if (c == '-') neg = 1, c = getchar(); 10 if (c == EOF) return EOF; 11 if (!isdigit(c)) return 0; 12 val = c - '0'; 13 while (isdigit(c = getchar())) val = val * 10 + (c - '0'); 14 *n = neg ? -val : val; 15 ungetc(c, stdin); // ★ 16 return 1; 17} 18 19int get_str(char *s) 20{ 21 int c; 22 while (isspace(c = getchar())) ; 23 if (c == EOF) return EOF; 24 *s++ = c; 25 while ((c = getchar()) != EOF && !isspace(c)) *s++ = c; 26 *s = '\0'; 27 if (c != EOF) ungetc(c, stdin); // ★ 28 return 1; 29} 30 31int main(void) 32{ 33 int height, weight; 34 char unit1[8], unit2[8]; 35 if (get_num(&height) != 1) return 1; 36 if (get_str(unit1) != 1) return 1; 37 if (get_num(&weight) != 1) return 1; 38 if (get_str(unit2) != 1) return 1; 39 printf("height:%d%s, wieght:%d%s\n", height, unit1, weight, unit2); 40}

実行例

text

1173cm 65kg 2height:173cm, weight:65kg

投稿2020/11/02 00:17

kazuma-s

総合スコア8224

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

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

0

ベストアンサー

c=getchar();あるいはc=getc(stdio);で読み込んだ1文字を、読まなかったことにすると言うことです。
次にgetchar()をするとその文字がもう一度読まれます。
「1文字余分に読み過ぎちゃった」という場合に使います。

山に積んであるトランプを、「赤いカードだけできるだけたくさん取ってください」と言われたら、上から順番にめくって赤だったらもらって、黒が出た時点でその黒カードを山に戻して終わりますよね?それと同じです。

投稿2020/11/01 16:28

otn

総合スコア85901

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

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

user012

2020/11/01 16:42

分かりやすい例ありがとうございます。 これを使った簡単なプログラムってありますか?
SaitoAtsushi

2020/11/01 18:46

トークナイザが典型的な用途ですね。
otn

2020/11/02 09:04

例としては、トランプの例のように、「英数字で出来ている単語を取り出す」ようなプログラムをgetchar()のような1文字ずつ取得して実現する場合ですね。
user012

2020/11/02 09:22

ありがとうございます。 ungetcの働きはおかげさまで理解できたのですが、 ungetc(c, stdin); 引数にstdinって書く理由を聞いてもいいですか?
otn

2020/11/02 09:30

ファイルは複数あり得るので、どのファイルか指定が必要です。 c自体にはstdinから取った文字だという情報は無いので。 (実際には、fopenの返り値やstdin/stdout/stderr等のファイルの識別子はストリームと呼ばれます)
user012

2020/11/02 09:35

標準入力ストリームから取ったからstdinと書いてるってことですか? ファイルから取ってたらそのファイルへのポインタを書くって理解でいいですか?
otn

2020/11/02 09:40

というか、どのストリームに返すかです。 ストリームAから取った文字をストリームBにungetcで突っ込むのも一応可能です。使い所が不明ですが。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問