扫描集在以下C代码中的不同行为
对于扫描集中的0-9范围,如果字符串输入为12345,则此IsNice输出为12345,这是正确的,但是对于输入,此IsNice 12345输出为@,这是错误的,我想,为什么这是错误的扫描集在以下C代码中的不同行为,c,C,对于扫描集中的0-9范围,如果字符串输入为12345,则此IsNice输出为12345,这是正确的,但是对于输入,此IsNice 12345输出为@,这是错误的,我想,为什么这是错误的 /* A simple scanset example */ #include <stdio.h> int main(void) { char str[128]; printf("Enter a string: "); scanf("%[9-0]s", str);
/* A simple scanset example */
#include <stdio.h>
int main(void)
{
char str[128];
printf("Enter a string: ");
scanf("%[9-0]s", str);
printf("You entered: %s\n", str);
return 0;
}
/*一个简单的扫描集示例*/
#包括
内部主(空)
{
char-str[128];
printf(“输入字符串:”);
scanf(“%[9-0]s”,str);
printf(“您输入了:%s\n”,str);
返回0;
}
我预计该代码的o/p为12345,与12345相同,但实际o/p为@您的代码具有未定义的行为。您没有初始化
str
,并且第二次输入时scanf
没有读取任何字段(“thisisnice12345”没有以数字开头),因此没有写入str
。如果您正在printf
-ingstr
,则您正在读取一个未初始化的变量,该变量是未定义的行为
您需要检查
scanf
的返回值<只有当scanf
返回1时,才会写入code>str。您的代码具有未定义的行为。您没有初始化str
,并且第二次输入时scanf
没有读取任何字段(“thisisnice12345”没有以数字开头),因此没有写入str
。如果您正在printf
-ingstr
,则您正在读取一个未初始化的变量,该变量是未定义的行为
您需要检查
scanf
的返回值str
仅在scanf
返回1时才被写入。以下是程序的改进版本:
#include <stdio.h>
int main(void)
{
char str[128];
printf("Enter a string: ");
if(scanf("%[0-9]", str) == 1)
printf("You entered: \"%s\"\n", str);
else printf("You entered nothing.\n");
return 0;
}
#包括
内部主(空)
{
char-str[128];
printf(“输入字符串:”);
如果(scanf(“%[0-9]”,str)==1)
printf(“您输入:\%s\”\n,str);
else printf(“您没有输入任何内容。\n”);
返回0;
}
正确的扫描集为
%[0-9]
,数字按顺序排列,尾随的s
。(在这种情况下,尾随的s
是无害的,但在其他情况下可能会导致问题。)更重要的是,如果scanf
返回0,则表示它不匹配任何内容,因此在str
中不存储任何内容。以下是程序的改进版本:
#include <stdio.h>
int main(void)
{
char str[128];
printf("Enter a string: ");
if(scanf("%[0-9]", str) == 1)
printf("You entered: \"%s\"\n", str);
else printf("You entered nothing.\n");
return 0;
}
#包括
内部主(空)
{
char-str[128];
printf(“输入字符串:”);
如果(scanf(“%[0-9]”,str)==1)
printf(“您输入:\%s\”\n,str);
else printf(“您没有输入任何内容。\n”);
返回0;
}
正确的扫描集为
%[0-9]
,数字按顺序排列,尾随的s
。(在这种情况下,尾随的s
是无害的,但在其他情况下可能会导致问题。)更重要的是,如果scanf
返回0,这表示它不匹配任何内容,因此在str
scanf
函数族中不存储任何内容。
但它有一些能力。如果要读取用户输入的第一个数字,可以使用:
只读取一个数字(警告其%[0-9]
,而不是0-9
)9-0
读取除数字以外的所有内容%[^0-9]
读取除数字外的所有内容并忽略它%*[^0-9]
/* A simple scanset example */
#include <stdio.h>
int main(void)
{
char str[128];
int ret;
printf("Enter a string: ");
/* Try to read a number at input start */
ret = scanf("%[0-9]", str);
if (1 != ret){
/* if reading failed, try to re-read the input,
ignoring all that is before the number */
ret = scanf("%*[^0-9]%[0-9]", str);
}
if (1 != ret)
printf("no match");
else
printf("You entered: %s\n", str);
return 0;
}
但在这段代码中,您必须处理一个新的事实:如果用户输入的数字太大,如何处理?(strlen
可以提供帮助,或者strto[u]l
…)
scanf
功能系列无法启动。
但它有一些能力。如果要读取用户输入的第一个数字,可以使用:
只读取一个数字(警告其%[0-9]
,而不是0-9
)9-0
读取除数字以外的所有内容%[^0-9]
读取除数字外的所有内容并忽略它%*[^0-9]
/* A simple scanset example */
#include <stdio.h>
int main(void)
{
char str[128];
int ret;
printf("Enter a string: ");
/* Try to read a number at input start */
ret = scanf("%[0-9]", str);
if (1 != ret){
/* if reading failed, try to re-read the input,
ignoring all that is before the number */
ret = scanf("%*[^0-9]%[0-9]", str);
}
if (1 != ret)
printf("no match");
else
printf("You entered: %s\n", str);
return 0;
}
但在这段代码中,您必须处理一个新的事实:如果用户输入的数字太大,如何处理?(strlen
可以提供帮助,或者strto[u]l
…)
首先:字符s
不属于扫描集说明符。它是%[…]
,而不是%[…]s
!
现在C标准说
- 如果
字符在扫描列表中,并且不是第一个字符,也不是第二个字符,其中第一个字符是-
,也不是最后一个字符,则行为由实现定义李>^
scanf("%[9-0]", str);
是否定义了实现。允许实现以was%[-09]
或任何其他实现定义的方式运行
例如,现在文档中的连字符表示字符范围,但由实现决定。即使如此,%[9-0]
是否包含该范围内的所有字符仍值得怀疑。总之,最好不要编写这样的代码。如果不指定缓冲区长度,scanf
是危险的。由于您受到了一个兼容性错误的困扰,因此最好不要再猜测不同平台上的行为,只需编写
int rv = scanf("%127[0123456789]", str);
if (rv == 1) {
...
}
首先:字符s
不属于扫描集说明符。它是%[…]
,而不是%[…]s
!
现在C标准说
- 如果
字符在扫描列表中,并且不是第一个字符,也不是第二个字符,其中第一个字符是-
,也不是最后一个字符,则行为由实现定义李>^
scanf("%[9-0]", str);
是否定义了实现。允许实现以was%[-09]
或任何其他实现定义的方式运行
例如,现在文档中的连字符表示字符范围,但由实现决定。即使如此,%[9-0]
是否包含该范围内的所有字符仍值得怀疑。总之,这比