scanf() 系列函数返回成功分配的数量。如果代码需要三个输入项,则无法仅从 sscanf() 返回的值判断是否提供了三个或更多输入项。
scanf() 函数通过读取字符、尝试匹配该字符、进行赋值(如果适用)然后移动到下一个字符或从函数调用返回来操作。有一个转换说明符%n,它存储到目前为止在此过程中读取的字符数(不增加读取的字符数)。此转换说明符可用于确定输入是否已被 sscanf() 调用耗尽。
下面的代码提供了一个演示。 fgets() 收集的输入行包含换行符,除非输入太大而无法放入缓冲区数组。这里buffer[] 足够大,可以存储合理大小的输入,但更健壮的代码会更仔细地处理超大输入。当sscanf()扫描输入字符串时,会依次读取每个字符,直到出现匹配失败或到达字符串末尾,所以匹配"%d %d %d %n"后预期读取的字符数与输入的长度相同字符串,包括任何尾随空白字符。
#include <stdio.h>
#include <string.h>
#define BUF_SZ 1024
int main(void)
{
char buffer[BUF_SZ];
int x, y, z;
int pos;
printf("Enter three integers: ");
fflush(stdout);
// get user input
if (fgets(buffer, sizeof buffer, stdin) != NULL) {
// first check: does input match 3 integers?
if (sscanf(buffer, "%d %d %d %n", &x, &y, &z, &pos) != 3) {
puts("Incorrectly formatted input");
} else {
// second check: did sscanf() finish at the end of the buffer?
int expected = strlen(buffer);
if (pos != expected) {
puts("Extra input in buffer");
printf("expected = %d, pos = %d\n", expected, pos);
} else {
// everything OK
printf("You entered: %d, %d, %d\n", x, y, z);
}
}
}
return 0;
}
示例交互:
>$ ./a.out
Enter three integers: 1 2 3
You entered: 1, 2, 3
>$ ./a.out
Enter three integers: 1 2
Incorrectly formatted input
>$ ./a.out
Enter three integers: 1 2 3 4
Extra input in buffer
expected = 8, pos = 6
如果希望禁止尾随 空格 字符,则可以使用 "%d %d %d%n" 代替。请注意,为了使其正常工作,必须从buffer[] 中删除换行符,以便不将其计为额外输入。一种典型的方法是使用buffer[strcspn(buffer, "\r\n")] = '\0':
int main(void)
{
char buffer[BUF_SZ];
int x, y, z;
int pos;
printf("Enter three integers: ");
fflush(stdout);
// get user input
if (fgets(buffer, sizeof buffer, stdin) != NULL) {
// first check: does input match 3 integers?
if (sscanf(buffer, "%d %d %d%n", &x, &y, &z, &pos) != 3) {
puts("Incorrectly formatted input");
} else {
// remove trailing newline character
buffer[strcspn(buffer, "\r\n")] = '\0';
// second check: did sscanf() finish at the end of the buffer?
int expected = strlen(buffer);
if (pos != expected) {
puts("Extra input in buffer");
printf("expected = %d, pos = %d\n", expected, pos);
} else {
// everything OK
printf("You entered: %d, %d, %d\n", x, y, z);
}
}
}
return 0;
}