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

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

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

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

データ構造

データ構造とは、データの集まりをコンピュータの中で効果的に扱うために、一定の形式に系統立てて格納する形式を指します。(配列/連想配列/木構造など)

Q&A

解決済

3回答

698閲覧

control + D で期待どうりに動かないことについて。

Yudachi_Siki

総合スコア3

C

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

データ構造

データ構造とは、データの集まりをコンピュータの中で効果的に扱うために、一定の形式に系統立てて格納する形式を指します。(配列/連想配列/木構造など)

0グッド

0クリップ

投稿2021/04/29 08:56

前提・実現したいこと

C言語を使っています。
データを線形リストで登録し、その後削除したい情報をキーとして入力し、削除するというプログラムにしたいです。
しかし、ターミナル上で control + D で 削除する対象の key を入力できるようになるはずがその動作を無視して終わってしまいます。
23行目が怪しいと思っているのですが、自分の力では解決できません。よろしくおねがいします。

発生している問題・エラーメッセージ

CLang 1111-2222 Java 3333-4444 Python 6666-7777 Python 6666-7777 Java 3333-4444 CLang 1111-2222 ←これを入力後、contlol + D Key Name                 ←飛ばされる Python 6666-7777 Java 3333-4444 CLang 1111-2222

該当のソースコード

C言語

1#include <stdio.h> 2#include <stdlib.h> 3#include <string.h> 4 5struct tfield{ 6 char name[20]; 7 char tel[20]; 8 struct tfield *pointer; 9}*head; 10 11struct tfield *talloc(void); 12void genlist(void); 13void displist(void); 14void del(char *); 15 16int main(void) 17{ 18 char key[20]; 19 20 genlist(); 21 displist(); 22 23 while(printf("Key Name \n"),(scanf("%s",key))!=EOF){ 24 del(key); 25 } 26 27 displist(); 28 return 0; 29} 30 31void del(char *key) 32{ 33 struct tfield *p,*old; 34 35 p=old=head; 36 while(p!=NULL){ 37 if(strcmp(key,p->name)==0){ 38 if(p==head) 39 head=p->pointer; 40 else 41 old->pointer=p->pointer; 42 return; 43 } 44 old=p; 45 p=p->pointer; 46 } 47 printf("キーデータが見つかりません\n"); 48} 49 50 51void genlist(void) 52{ 53 struct tfield *p; 54 55 head=NULL; 56 while(p=talloc(),scanf("%s %s",p->name,p->tel)!=EOF){ 57 p->pointer=head; 58 head=p; 59 } 60} 61 62void displist(void) 63{ 64 struct tfield *p; 65 p=head; 66 while(p!=NULL){ 67 printf("%15s%15s\n",p->name,p->tel); 68 p=p->pointer; 69 } 70} 71struct tfield *talloc(void) 72{ 73 return (struct tfield *)malloc(sizeof(struct tfield)); 74}

試したこと

23行目 判定を != → == にすると無限ループ。

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

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

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

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

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

itagagaki

2021/04/29 09:15

ターミナルの問題のような気がします。 stty -a の出力を見せてください。
dodox86

2021/04/29 09:15

ターミナル上でcontrol+Dの入力はEOF(End of file)を示すことになるので、scanfがEOF(-1)を返す仕様です。ですので > ターミナル上で control + D で 削除する対象の key を入力できるようになるはず と言うこと自体が成り立ちません。
itagagaki

2021/04/29 09:21

成り立つかどうかは処理系によるかもです。 なので処理系によっては動くかもしれないけど適切ではないかもですね。 Cygwinでは動いちゃいました。
dodox86

2021/04/29 09:23 編集

@itagagakiさん ご指摘ありがとうございます。 > 成り立つかどうかは処理系によるかもです。 確かにそうですね。WindowsコマンドプロンプトではCTRL+Zですし。
Yudachi_Siki

2021/04/29 09:23

@itagagaki さん % stty -a speed 9600 baud; 24 rows; 80 columns; lflags: icanon isig iexten echo echoe -echok echoke -echonl echoctl -echoprt -altwerase -noflsh -tostop -flusho pendin -nokerninfo -extproc iflags: -istrip icrnl -inlcr -igncr ixon -ixoff ixany imaxbel iutf8 -ignbrk brkint -inpck -ignpar -parmrk oflags: opost onlcr -oxtabs -onocr -onlret cflags: cread cs8 -parenb -parodd hupcl -clocal -cstopb -crtscts -dsrflow -dtrflow -mdmbuf cchars: discard = ^O; dsusp = ^Y; eof = ^D; eol = <undef>; eol2 = <undef>; erase = ^?; intr = ^C; kill = ^U; lnext = ^V; min = 1; quit = ^\; reprint = ^R; start = ^Q; status = ^T; stop = ^S; susp = ^Z; time = 0; werase = ^W; となりました。
itagagaki

2021/04/29 09:27

eof = ^D ですね。 そこは問題ないですね。 他の方がおっしゃっているように、お使いの処理系では、一度EOFを送ったら、その後scanfしてもEOFしか返らないシステムなのっぽいですね。 なので、EOFで終わりにするのではなく、何か特別なワードで終わりにするのがよさそうですね。
Yudachi_Siki

2021/04/29 09:30

みなさんありがとうございます。自分の中ではほとんど解決したと思っています。初めて質問してみたのですが、返信がとても早くてびっくりするとともに、ありがたく思いました。次回がありましたらよろしくおねがいします。
guest

回答3

0

EOF状態が保持されてしまっているのが問題。
clearerr(stdin);でEOF状態を外すか、違う条件をつけて判定条件を変えることで解決。

投稿2021/04/29 14:18

Yudachi_Siki

総合スコア3

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

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

0

ベストアンサー

C

1 clearerr(stdin);

で、(エラー状態と)EOF状態をクリアできます。

投稿2021/04/29 11:37

otn

総合スコア85901

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

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

Yudachi_Siki

2021/04/29 14:16

解決しました!!ありがとうございます!!!
otn

2021/04/29 14:32

× 期待どうり ○ 期待どおり(通り)
Yudachi_Siki

2021/04/30 01:36

日本語も勉強します。 ありがとうございます。
guest

0

Ctrl+Dがだめなら、Ctrl+Cではどうでしょうか

投稿2021/04/29 09:06

y_waiwai

総合スコア88042

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

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

Yudachi_Siki

2021/04/29 09:08

Ctrl+Cだと実行中のプログラムそのものが終了してしまいます。
y_waiwai

2021/04/29 09:12

一度EOFが検出されたら、それ以降ずっとEOFのままなので、そう言う動作となってしまいますな
y_waiwai

2021/04/29 09:13

ということで、こういう用途の場合は、EOF以外の文字キーを検出するようにしないとダメです
Yudachi_Siki

2021/04/29 09:15

なるほど。では次の判定のときはEOF以外で判定するようにしてみます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問