当第一个跟踪失败时,为什么我不能再对同一个变量使用scanf
请参阅以下代码:
#include int main(int argc, char const *argv[]) { int n; int i = scanf("%d", &n); printf("%d\n", i); int j = scanf("%d", &n); printf("%d\n", j); return 0; }
假设我第一次为n
输入一个字符串, scanf
将返回0
; 但是,为什么它不允许我第二次输入n
的值而j
是自动0
? 即使我第一次键入错误的值,我该怎么做才能让我再次输入n
值?
您几乎肯定会输入一个非数字值,这将导致第一个scanf
失败,返回零并且(这是重要的位) 将流指针保留在scanf
调用之前的确切位置。
这意味着下次调用它时,它只会尝试读取相同的数据。
零返回值是一个死的赠品 – scanf
返回成功扫描的项目数,因此零表示您没有给它一个数字。
如果您输入数字,它可以正常工作,如下面的代码:
#include int main(int argc, char const *argv[]) { int n; int i = scanf("%d", &n); printf(">> %d %d\n", i, n); int j = scanf("%d", &n); printf(">> %d %d\n", j, n); return 0; }
当您运行它并输入41
和32
,您会看到:
41 >> 1 41 32 >> 1 32
在他们职业生涯的某个阶段,每个C程序员都会遇到用户输入该语言的不足之处。 基于行的输入最好的选择是简单地找到一个能很好地运行的函数,然后在结果字符串上使用sscanf
。
确保行是基本单元,并且可以处理缓冲区溢出并确保过多的数据不会“破坏”未来的输入。
这是我之前准备的。
您输入的非数字字符串不会被scanf
。
相反,您可以像这样使用fgets
和sscanf
:
#include int main(void) { int n; char str[100]; fgets(str, sizeof(str), stdin); int i = sscanf(str, "%d", &n); printf("%d\n", i); fgets(str, sizeof(str), stdin); int j = sscanf(str, "%d", &n); printf("%d\n", j); return 0; }
在重新输入输入并读取它们之前,您可以忽略其余部分。 你可以使用以下方法忽略其余部分:
scanf("%[^\n]*\n");
如果输入数字,您的代码将正常工作。 但是,在输入字符串时,必须先从输入流中删除该字符串,然后再使用它。
例如:
#include int main(int argc, char const *argv[]) { int n; char c; int i = scanf("%d", &n); printf("%d\n", i); //Remove the previous string from the input stream while ( (c = getchar()) != '\n' && c != EOF ); int j = scanf("%d", &n); printf("%d\n", j); return 0; }
输入为整数时输出
100 1 200 1
输入为字符串时输出
abcd 0 efghi 0
进一步参考: 为什么每个人都说不使用scanf? 我该怎么用?