免责声明。我见过很多问题,包括几乎完全相同的代码片段,但似乎没有人回答这个问题。
对于入门级 CS 课程,我们的任务是制作一个简单的程序,该程序接受用户输入的 ID、姓名和年龄并将其保存到文件中。这很简单,我很快就让它工作了。问题是,为了得到一部分,名称输入,正常工作,我不得不“欺骗”我遇到的问题。
有问题的代码片段。
int id, age;
char name[40]={0};
printf("ID: ");
scanf("%i",&id);
printf("Name: ");
scanf("%*c");
scanf("%[^\n]%*c",name);
printf("Age: ");
scanf("%i",&age);
Run Code Online (Sandbox Code Playgroud)
这工作正常。但是这条线让我很恼火;scanf("%*c");它的唯一目的是处理'\n'潜伏在流中的字符,可能来自先前的输入。出于某种原因,我觉得这是作弊,或者如果我必须使用这种解决方法,我做错了什么。任何提示表示赞赏。
但是这条线让我很恼火;scanf("%*c"); 它的唯一目的是处理潜伏在流中的 '\n' 字符,可能来自先前的输入。
scanf()对于读取单个字符来说是非常重量级的。我通常getchar()会这样做,如果您不在乎结果,则只需忽略结果。
但是,对于您的特定情况,我会同意@OlafDietsche 在评论中提出的建议:在格式字符串的开头插入一个空格(或换行符或制表符)以用于下一个scanf:
scanf(" %[^\n]%*c",name);
Run Code Online (Sandbox Code Playgroud)
这将匹配任何零个或多个空白字符的运行,因此会吃掉你的换行符,加上任何后续的空白行和下一行具有任何非空白的任何前导空白。无论如何,这是大多数其他字段指令的标准行为,这就是为什么您的数字字段没有相同问题的原因,但它有意不为%[和%c字段自动完成,以便它们可以读取和返回空格。
这也意味着您不需要在名称行末尾显式使用换行符,或者......
scanf(" %[^\n]",name);
Run Code Online (Sandbox Code Playgroud)
...因为它将%i在后续scanf()调用中由指令自动使用。