C语言gets函数的问题

使用两个连续的gets对两个字符数组c1与c2进行输入操作。当两个字符数组都是长度为一的字符数组时,第二个gets执行完毕后c1的值会被修改为'\000'。
如果将c1与c2的长度改为大于一的长度,c1在c2被赋值后就不会被修改为'\000'。这是为什么?

img

img

不知道你这个问题是否已经解决, 如果还没有解决的话:
  • 你可以看下这个问题的回答https://ask.csdn.net/questions/7739805
  • 除此之外, 这篇博客: C语言:使用字符串处理函数中的  2.gets函数——输入字符串的函数 部分也许能够解决你的问题, 你可以仔细阅读以下内容或者直接跳转源博客中阅读:

    其一般形式为:

    gets(char str[])

       1.从终端输入一个字符串到字符数组,并得到一个函数值。

       2.该函数值是字符数组的起始地址。

    示例代码:

    #include<stdio.h>
    int main()
    {
    	char str[10];
    	gets(str);
    	puts(str);
    	return 0;
    }
  • 以下回答来自chatgpt:
    1. gets函数是C语言标准库中的一个字符串输入函数,其原型为char gets(char str),作用是从标准输入流中读取字符,遇到换行符或者文件结束符时停止读取,并将读取到的字符存储在str所指向的字符数组中。
    2. 定义两个字符数组c1和c2,使用gets分别对它们进行输入操作,代码如下:
    char c1[100], c2[100];
    gets(c1);
    gets(c2);
    
    1. 当两个字符数组都是长度为一的字符数组时,第二个gets会将输入的第一个字符存储到c2中,而输入的换行符则会留在输入缓冲区中,因此在第二次调用gets函数时,它会读取到这个换行符,并将其存储到c1中,导致c1的值被修改为'\000'。可以使用下面的代码来验证:
    char c1[1], c2[1];
    gets(c1);
    gets(c2);
    printf("c1: %c, c2: %c\n", c1[0], c2[0]);
    

    输入字符a和字符b,输出结果为"c1: , c2: b",可以看到c1的值被修改为了空字符。

    1. 当c1和c2的长度大于一时,输入缓冲区中剩余的换行符会被第一次调用gets函数读取并丢弃,因此第二次调用gets时不会读取到换行符,也就不会修改c1的值。

如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^

回答部分参考、引用ChatGpt以便为您提供更准确的答案:

根据您提供的图片和问题描述,可以得出以下解释:

当使用两个连续的gets函数对字符数组c1c2进行输入操作时,gets函数会读取输入的字符串,并将其存储到对应的字符数组中。然而,gets函数存在潜在的缓冲区溢出问题。

在第一个gets函数执行完毕后,输入的字符串会存储到c1中,但由于c1的长度为1,只能容纳一个字符。如果输入的字符串长度大于1,那么会发生缓冲区溢出,超出部分的字符可能会覆盖其他内存空间。这可能导致未定义的行为和程序崩溃。

在第二个gets函数执行时,由于c1的长度为1,gets函数会尝试将输入的字符串存储到c1中。但是由于长度不足,超出的字符将会导致缓冲区溢出。为了避免这种情况,C语言标准库函数gets在存储字符串时会自动在字符串的末尾添加一个空字符\0,用来表示字符串的结束。所以c1的值会被修改为\0,表示一个空字符串。

当将c1c2的长度改为大于一的长度时,字符数组能够容纳更多的字符,而不会发生缓冲区溢出。因此,在第二个gets函数执行后,c1的值不会被修改为\0,而是保留之前输入的字符串。

总结来说,这个现象是由于使用长度为1的字符数组时,输入的字符串长度超过了数组容量,导致发生缓冲区溢出,而C语言标准库函数gets为了确保字符串的正确表示,在存储时会在末尾添加空字符\0

建议在实际编程中避免使用不安全的函数gets,而是使用更安全的输入函数如fgets,并且在使用字符数组时确保其长度足够容纳输入的字符串。

如果您有进一步的问题,请随时提问。