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::-)…-所以这个答案肯定证明你是人类!干杯…;-)