在 Windows 上对字符串使用 scanf 时的双 Ctrl+D 输入

Double Ctrl+D input when using scanf for strings on Windows

提问人:Carlos Pinto 提问时间:1/26/2017 最后编辑:hydeCarlos Pinto 更新时间:1/26/2017 访问量:853

问:

情况是这样的,我有一个代码可以读取值,直到用户输入 Ctrl+D,但问题是我必须输入两次才能成功退出循环,我认为这与 Ctrl+D 与缓冲区的剩余部分一起插入到字符串中的事实有关,因此没有注册为 EOF 而只是字符串中的另一个字符,只有第二个 Ctrl+D 将保存在 int 变量中,实际上停止了读取循环。为了解决这个问题,我添加了while(getchar() != '\n')来查看它是否解决了问题,但没有结束。 这是我的代码:

typedef struct {
  char nome[50];
  int tempo;
  int ncertas;
} equipa;


int ler_equipas(equipa *resultados)
{
    int x, r1, r2 ,r3 ,r4, r11, r22, r33 ,r44, rcertas = 0, i = 0;
    scanf ("%d %d %d %d", &r1, &r2, &r3, &r4);
    while (scanf ("%s %d %d %d %d %d", resultados[i].nome, &resultados[i].tempo, &r11, &r22, &r33, &r44 ) == 6 )
    {
        i++;
        if (r1 == r11) rcertas++;
        if (r2 == r22) rcertas++;
        if (r3 == r33) rcertas++;
        if (r4 == r44) rcertas++;
        resultados[i-1].ncertas = rcertas;
        rcertas = 0;
        while((x=getchar()) != '\n');
    }
    return i;
}

输入/输出如下(“>>”表示输出):

1 2 3 4
>> correct answers are 1 2 3 4
Team1 234 1 2 3 4
>> values inputed for team time and answers: Team1 234 1 2 3 4
>> getchar value was (ASCII): 10
>> Next read:

Team2 400 1 3 2 4
>> values inputed for team time and answers: Team2 400 1 3 2 4
>> getchar value was (ASCII): 10
>> Next read:
>>
^D
^D
>> return i was reached
>> Number of teams: 2
>> Team "Team1" took 234 seconds and answered 4 questions correctly
>> Team "Team2" took 400 seconds and answered 2 questions correctly
C 字符串 scanf eof

评论

0赞 hyde 1/26/2017
我建议获取两个调用以及调用变量的返回值,然后在调试器下运行代码(或添加调试打印)以查看这些返回的内容以及代码流的进展情况。scanfgetchar
0赞 hyde 1/26/2017
实际上,由于这不是一个完整的程序,而且代码似乎不应该有您描述的错误(它确实有一些其他严重的问题,基本上您没有正确检查和的返回值),似乎问题很可能出在您没有向我们展示的代码部分......scanfgetchar
0赞 Carlos Pinto 1/26/2017
我在返回 i 之前添加了一个 printf,它只在双 ctrl+D 之后打印,我还在整个代码中添加了 printf 以查看是否没有正确读取某些内容,并且一切似乎都检查出来了,变量具有它们应该具有的值,并且 getchar allways 捕获换行符,这在理论上意味着换行符从缓冲区中删除, 会不会是编译器问题?
0赞 Support Ukraine 1/26/2017
无法在我的 Linux 上重现。您使用哪种系统?
0赞 Carlos Pinto 1/26/2017
我正在使用 Windows 10 代码块,无论如何这不是完整的代码,它只是一个函数,我认为完整的代码太长了,这是在 main() 中调用的第一个函数,在此之前只进行了变量声明,所以我认为这不是原因

答:

0赞 bitflip-at 1/26/2017 #1

我还没有尝试过。但我记得有同样的问题......

试试这个: 如何清除 C 中的输入缓冲区?

while ((c = getchar()) != '\n' && c != EOF) { }

这是清除输入缓冲区的一种方式。
但这是在调用清除输入缓冲区之后。
scanf();

此致敬意

1赞 Support Ukraine 1/26/2017 #2

由于您使用的是 windows,因此您应用于模拟ctrl+zEOF

查看 https://stackoverflow.com/a/16136924/4386427

使用 时,第一个与首字母匹配,以便继续扫描。ctrl+dctrl+d%s

第二个将不匹配,因此扫描终止。由于扫描的元素数不是 6,因此循环终止。ctrl+d%dwhile

因此,两个终止了该功能。单身也将终止该计划。ctrl+dctrl+z

评论

0赞 Carlos Pinto 1/26/2017
你是绝对正确的,直到现在我一直在使用 Ubuntu,直到现在才开始使用 Windows,我什至没有想到 Ctrl+D 的协议会有所不同,非常感谢!