C程序停止与scanf_s一起工作
我是一名编程新手,在编写一段代码时遇到了麻烦。我试图输入一个单词,但当我运行程序并输入单词时,它停止工作 代码如下:C程序停止与scanf_s一起工作,c,tr24731,C,Tr24731,我是一名编程新手,在编写一段代码时遇到了麻烦。我试图输入一个单词,但当我运行程序并输入单词时,它停止工作 代码如下: int main(void){ char a[]= ""; printf("Enter word:\n"); scanf_s("%s", a); return 0; } 我试着给一个[]一个20的大小,并使用%19s作为另一个问题,但这也不起作用 编辑1。已更改字符a[]=“”到字符a[20]={0}但它不起作用 编辑2。添加了si
int main(void){
char a[]= "";
printf("Enter word:\n");
scanf_s("%s", a);
return 0;
}
我试着给一个[]一个20的大小,并使用%19s作为另一个问题,但这也不起作用
编辑1。已更改字符a[]=“”代码>到字符a[20]={0}代码>但它不起作用
编辑2。添加了sizeof(a),代码运行正常。此外,我删除了{0},但我不知道这是否有什么不同
最终代码:
int main(void){
char a[20];
printf("Enter word:\n");
scanf_s("%19s", a, sizeof(a));
return 0;
}
使用
创建一个足以容纳单个字节的数组。您必须分配足够的空间,例如:
char a[20] = {0}; // Can hold a string length 19 + \0 termination
使用您的方法,您将得到溢出,因为scanf\u s
将在内存中写入比您分配的更多的内容,从而导致分段故障。诊断
代码中存在(至少)两个问题:
int main(void){
char a[]= "";
printf("Enter word:\n");
scanf_s("%s", a);
return 0;
}
您没有提供任何有用的空间来存储字符串。(最初的问题定义为:chara[]=”;
,需要注意的是,它是一个长度为1的数组,尽管它只能容纳长度为0的字符串。)
您还没有告诉scanf_s()
字符串有多大。它要求在指向字符串的指针之后有一个长度参数
Microsoft对的定义指定:
与scanf
和wscanf
不同,scanf\u s
和wscanf\u s
要求为c
、c
、s
、s
或[]/code>中包含的字符串控制集类型的所有输入参数指定缓冲区大小。缓冲区大小(以字符为单位)作为附加参数传递,紧跟在指向缓冲区或变量的指针之后。例如,如果您正在读取一个字符串,则该字符串的缓冲区大小传递如下:
char s[10];
scanf_s("%9s", s, _countof(s)); // buffer size is 10, width specification is 9
缓冲区大小包括终止null。您可以使用宽度规范字段来确保读入的令牌适合缓冲区。如果未使用宽度规范字段,并且读入的令牌太大,无法放入缓冲区,则不会向该缓冲区写入任何内容
注意
大小参数的类型为无符号
,而不是大小
\u countof()
运算符是Microsoft的扩展。它大致相当于sizeof(s)/sizeof(s[0])
,在这种情况下,它与sizeof(s)
相同,因为sizeof(char)==1
请注意,size参数是无符号的
,而不是预期的size\u t
。这是Microsoft实现功能与ISO/IEC 9899:2011附录K之间的差异之一。本标准中规定的尺寸在技术上是rsize\u t
,但定义为size\u t
,范围有限(因此为r
):
类型是rsize\u t
,它是size\u t
类型
但脚注(未显示)涉及RSIZE_MAX
的定义
另见
修正问题中的代码
引用自Microsoft的示例主要展示了如何修复代码。你需要:
int main(void)
{
char a[4096];
printf("Enter word:\n");
if (scanf_s("%s", a, (unsigned)sizeof(a)) != 1) // Note cast!
fprintf(stderr, "scanf_s() failed\n");
else
printf("scanf_s() read: <<%s>>\n", a);
return 0;
}
int main(无效)
{
chara[4096];
printf(“输入单词:\n”);
如果(scanf_s(“%s”,a,(unsigned)sizeof(a))!=1)//注意!
fprintf(stderr,“scanf_s()失败\n”);
其他的
printf(“scanf_s()读取:\n”,a);
返回0;
}
请注意,我检查了scanf_s()
的结果,而不是仅仅假设它工作,并报告了标准错误的错误。您已经声明并清空了数组<代码>字符a[50]={0}代码>可能?无论如何,在它当前的结构中,它显然不起作用。显示大小为20
的变量是什么scanf\u s
?你的意思是scanf
对吗?相关问题:有一个scanf_s
的M$variant,我只是想给他指出正确的方向。如果大小为20,则应适用于长度为19的字符串。数组的长度为1字节(它包含一个'\0'
);C中没有大小为零的对象。我已经修复了断言chara[]=”代码>定义零大小数组。事实并非如此;它指定大小为1的数组。C中没有零大小的对象。不过,这并不能解决整个问题。scanf_s()谢谢我尝试了这个例子,程序成功了。尽管如此,我还是需要学习它,因为我不了解它的大部分内容。它的大部分内容和你的一样。对scanf_s()
的调用中还有一个额外的参数-这是对代码的关键修复。*scanf*()
函数返回成功转换的次数或EOF on error。在本例中,这有点迂腐,但最好检查每个输入操作是否成功。如果您没有遇到fprintf()
和stderr
,那么您可以将fprintf(stderr,…)
视为“用于编写错误消息的printf()
的变体”fprintf()
可用于写入任何打开的文件流,还有其他写入stderr
的方法。@alk:我这样做更多是为了避免做所有其他我应该做的事情。@JonathanLeffler::-)…-所以这个答案肯定证明你是人类!干杯…;-)