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

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

ただいまの
回答率

88.58%

while (scanf("%d %s", &key, name) != EOF)の挙動がおかしい

受付中

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 2,173

mercurian-teto

score 75

このサイトで自己参照構造体を勉強していたのですが、
while (scanf("%d %s", &key, name) != EOF)では
ctrl + zでループを抜けるはずですが、3回ctrl+zを入力しないとループが抜けません。

キーと名前(MAX:19文字)を入力(終了:CTRL+Z)
1 a
2 i
3 u
^Z
^Z
^Z
  3 u
  2 i
  1 a
続行するには何かキーを押してください . . .


環境もしくはプログラムが影響しているでしょうか。
環境はwindows10 pro 1803 、visual studio 2017です。回答お願いします。

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h> 
#include <string.h>
#include <stdlib.h>

struct list {
    int key;            /* キー */
    char name[20];        /* 名前 */
    struct list *next;        /* 次のデータへのポインタ */
};

struct list *add_list(int key, char *name, struct list *head);
void show_list(struct list *p);
void free_list(struct list *p);

int main(void)
{
    struct list *head;        /* 先頭ポインタ */
    char name[20];
    int key = 0;

    head = NULL;        /* 先頭ポインタにNULLを設定 */

    printf("キーと名前(MAX:19文字)を入力(終了:CTRL+Z)\n");
    while (scanf("%d %s", &key, name) != EOF) {
        /* リストにデータを登録 */
        head = add_list(key, name, head);
    }
    /* リストの表示 */
    show_list(head);

    /* リストの開放 */
    free_list(head);

    return 0;
}

/*** リストにデータを登録 ***/
struct list *add_list(int key, char *name, struct list *head)
{
    struct list *p;

    /* 記憶領域の確保 */
if ((p = (struct list *) malloc(sizeof(struct list))) == NULL) {
        printf("malloc error\n");
        exit(EXIT_FAILURE);
    }

    /* リストにデータを登録 */
    p->key = key;
    strcpy(p->name, name);

    /* ポインタのつなぎ換え */
    p->next = head;        /* 今までの先頭ポインタを次ポインタに */
    head = p;            /* 新たな領域を先頭ポインタに */

    return head;
}

/*** リストの表示 ***/
void show_list(struct list *p)
{
    while (p != NULL) {    /* 次ポインタがNULLまで処理 */
        printf("%3d %s\n", p->key, p->name);
        p = p->next;
    }
}

/*** リストの開放 ***/
void free_list(struct list *p)
{
    struct list *p2;

    while (p != NULL) {     /* 次ポインタがNULLまで処理 */
        p2 = p->next;
        free(p);
        p = p2;
    }
}
  • 気になる質問をクリップする

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

+1

scanf()は読み取った項目数を返します。従って上記の例だと2以外が帰ってくればエラーです。
EOFは通常(Windowsの時)帰ってきません。
「追記」
EOFを発生させるには、WindowsはCtl+Zとenterが必要です。LinuxのようなUNIX系はCtl+Dです。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

Visual Studio 2013 までは正常のようですが、Visual Studio 2015 と Visual Studio 2017 ではそのような現象になりますね。
Visual Studio 2015 で標準ライブラリのソースを全面的に C++ で書き直したようです。
その影響かバグと言ってもいいような仕様なんでしょうね。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

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

  • ただいまの回答率 88.58%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る