题
如何使用 scanf 验证用户输入。现在我有类似的东西,但不起作用。
笔记:我有 atoi 只是为了验证 scanf 验证是否有效。
scanf("%[0987654321.-]s",buf);
i = atoi(buf);
if(i)
index = i;
解决方案
使用 scanf()
对于用户输入来说通常是一个坏主意,因为失败会留下 FILE
指针指向未知位置。那是因为 scanf
代表“扫描格式化”,仅此而已 未格式化的 比用户输入。
我建议使用 fgets()
排队,然后是 sscanf()
在字符串上实际检查和处理它。
这还允许您检查字符串中是否有您想要的字符(通过循环或使用正则表达式),这是 scanf
函数族并不真正适合。
举例来说,使用 scanf()
与一个 "%d"
或者 "%f"
将停止在第一个非数字字符处,因此不会捕获尾随错误,例如 "127hello"
, ,这只会给你 127。并将其与无界一起使用 %s
只是 乞讨 缓冲区溢出。
如果您确实必须使用 []
格式说明符(在 scanf
或者 sscanf
),我不认为它应该跟随 s
.
并且,对于使用该建议的强大输入解决方案,请参阅 这里. 。一旦你有了一个字符串形式的输入行,你就可以 sscanf
尽您所能。
其他提示
您似乎想验证一个字符串作为输入。这取决于你是否想验证你的字符串包含双或INT。用于双以下检查(前缘和后空格是允许的)。
bool is_double(char const* s) {
int n;
double d;
return sscanf(s, "%lf %n", &d, &n) == 1 && !s[n];
}
sscanf
将返回转换(没有 '%N')中的项目。 n
将被设置为处理后的输入字符的量。如果所有的输入被处理,S [N]将返回终止0字符。这两个格式说明之间的空间占可选尾随空白。
有一个int下列检查,使用相同的技术:
bool is_int(char const* s) {
int n;
int i;
return sscanf(s, "%d %n", &i, &n) == 1 && !s[n];
}
有对一个问题此处 ,其中也包括这样做的更多的C ++“ISH的方式,比如使用字符串流和功能从提升,喜欢的lexical_cast等。它们一般应优于一样scanf函数的功能,因为它很容易忘记通过一些“%”到scanf函数,或某个地址。 scanf函数将无法识别,而是会做事情随心所欲,同时lexical_cast的,例如,会如果有什么是不正确的抛出异常。
我的方法将读取用户输入的字符串,然后将其转换为长使用strtol()
。 strtol()
返回指针,指向输入字符串的第一个字符它未能通过检查这个角色,你就会知道完整的字符串是否被解析,这样来处理这样:
char *string;
char *endptr;
long result;
scanf("%as", string);
errno = 0;
result = strtol(string, &endptr, 10);
if (ERANGE == errno)
printf("Input number doesn't fit into long\n");
else if (*endptr)
printf("%s is not a valid long number - it contains invalid char %c\n",
string, *endptr);
else
printf("Got %ld\n", result);
在此代码段scanf()
被指示足够使用格式修饰语“一个”(这是GNU扩展)自动分配string
大。如果不在GNU,手动分配string
并限制scanf()
格式最大大小。
这个方法允许更好的错误处理。
在第一个参数指定scanf
哪些转换说明。 scanf
会尝试将输入转化为格式,但有时你可能会惊讶它会对阵:)
你应该做的第一检查是从scanf函数的返回值(它会给你的匹配输入的数量)。如果你没有得到你期待那么这个数你知道的东西是错误的输入。在您的情况下,它应该是1。
if( scanf("%[0987654321.-]s", buf) == 1 )
{
if( sanit_check( buf ) )
{
/* good input */
}
else
{
/* invalid input */
}
}
else
{
/* invalid input */
}
除此之外,你需要做你自己的,你问scanf
做转换完整性检查。
如果你想只读了许多,使用方法:
int i;
scanf( "%d", &i );
如果您需要做更复杂的检查,你必须自己做。 scanf函数不会为你做。
“BUF”需要一个指针。它看起来像您按值传递。