我一直在整夜调试,控制台总是跳起来问我第二名跑步者的名字是非常令人困惑的,但是不要给我改变输入第一名跑步者的名字。
这是我的main.c中的段
Trunner runners[10];
Trunner best;
int n,i;
const char* name = "give the name for runner ";
const char* time = "give the time for runner ";
printf("How many names you have?");
scanf("%d",&n);
for(i=0;i<n;i++){
readTime(&runners[i],time);
}
for(i=0;i<n;i++){
readName(&runners[i],name);
}
这是我的runner.c
void readName(Trunner *runner, const char *prompt){
printf(prompt);
fgets (runner->name,30,stdin);
//getchar();
}
和我得到的,跑步者的名字应该与逗号在同一行,正如你所看到的,第一个跑步者的名字是空的。
How many names you have?3
give the time for runner 11:13
give the time for runner 14:14
give the time for runner 12:13
give the name for runner give the name for runner lily
give the name for runner lucy
the winner is:
, 11:13
, 11:13 0:0
lily
, 14:14 3:1
lucy
, 12:13 1:0
Press any key to continue . . .
答案 0 :(得分:1)
执行scanf
后,会有一个换行符。第一个fgets读取它,因此字符串保持为空。有几种选择如何避免这种情况,但最简单的方法是在scanf之后简单地执行一个fgets,将缓冲区读取到换行符。
另一个(可能更好)选项是在fflush(stdin);
之后调用scanf
。如果从控制台读取(看起来似乎是这种情况),这将在刷新输入缓冲区时发挥作用。
答案 1 :(得分:0)
您同时使用了scanf和fgets。这两个功能有点不同。就个人而言,我不会触摸scanf,因为它会像你自己看到的那样留在缓冲区中。
\ n(或换行符)几乎在每次输入后都会保留,但不同之处在于,如果它保留scanf("%d",&someVar)
,它大部分都不会跳过,因为/ n不能转换为%d BUT如果缓冲区中有\ n而你执行scanf("&c",&someVar)
或scanf("%s",someArray)
,那么因为\ n是一个字符,它会将它从缓冲区中拉出来,就好像你只是按下它一样。
请注意,您可以通过getchar()删除缓冲的\ n字符,但前提是您知道它在那里或您的程序将等待按键。如果您希望程序保持稳定,请不要使用fflush。解释http://www.gidnetwork.com/b-57.html。
你没有发布你的readTime函数,所以我无法给你精确的解决方案,但我可以建议每个输入使用fgets,然后转换为一个整数,你可以使用i=strtol(buffer,NULL,10)
为例(位于<stdlib.h>
)。我建议阅读关于strtol,strtod,strtok函数的内容,因为它们对于fgets的任何输入都是你需要的。