如何使用gets()函数直接写入指针?

时间:2014-03-29 23:33:39

标签: c pointers gets

我得到了这些测试代码并且好奇,为什么将指针传递给gets()会导致运行时错误?

void main()
{
    char *value="gogo";
    puts(value);
    value="11";
    puts(value);
    gets(value);
}

3 个答案:

答案 0 :(得分:2)

因为char *value="gogo";更有可能不会分配给 READ ONLY MEMORY

更好:

#include <stdio.h>
#include <string.h>

#define MAX_LINE 80

int main()
{
    char value[MAX_LINE] ="gogo";
    puts(value);
    strcpy (value, "11");
    puts(value);
    fgets(value, MAX_LINE, stdin);
    puts(value);
    return 0;
}

以下是一个包​​含更多详细信息的良好链接:Storage for Strings in C

PS:

gets()是邪恶的。尽可能避免使用它:Why gets() is bad

答案 1 :(得分:2)

指针value指向(与字符串文字相关联的静态数组)。

尝试修改字符串文字具有未定义的行为。在这种情况下,您的编译器将字符串"gogo"存储在操作系统标记为只读的内存中,并且尝试修改它会导致程序崩溃。

如果声明指向字符串文字的指针,则应将其定义为const

const char *value = "gogo";

因此编译器将诊断任何修改它的尝试。或者,如果您确实要修改字符串,请将其定义为数组:

char value[] = "gogo";

这意味着您无法为value分配值,但您可以使用strcpy进行更新。

还有一些问题:

void main()错了[*];正确的定义是int main(void)。如果您使用的是一本告诉您使用void main()的图书,请找一个更好的图书;它的作者不太了解C.

永远不要使用gets功能;它本质上是不安全的,并已从语言中删除。 (它不能防止输入比存储值的数组更长。)您可以使用fgets代替;它使用起来有点复杂,但它可以安全使用。

您需要添加

#include <stdio.h>

到源文件的顶部以使这些函数可见。如果您的编译器没有抱怨对未声明函数的调用,请找出如何提高其警告级别。

[*]说void main()错误略微夸大了案例。符合标准的编译器可能允许它,并且不需要编译器来抱怨它,但没有充分的理由来利用它。 int main(void)总是正确的。任何提倡使用void main()的C书或教程几乎都是由一个不太了解C语言的人写的,可以写书或教程。

答案 2 :(得分:1)

在这里,您的指针指向字符串文字("gogo")。字符串文字不保证是可写的。你需要分配自己的记忆:

char value[50] = "gogo";
...
gets(value);

然而,这不安全,因为gets不占用缓冲区的大小,因此可能会溢出缓冲区。 (这也可能导致运行时错误)。 从不使用gets,如联机帮助页所述:

  

<强> BUGS

     

永远不要使用gets()。因为在事先不知道数据的情况下无法判断将会读取多少个字符gets(),并且因为gets()将继续存储超过缓冲区末尾的字符,所以使用它是非常危险的。它已被用来打破计算机安全。请改用fgets()

分配自己的记忆要好得多:

char user_input[200];
fgets(user_input, 200, stdin);

您可能需要检查user_input,看看它是否以换行符结尾。如果是,那么fgets读取整行。如果它没有,则用户在该行中键入超过约200个字符,并且您需要阅读更多内容以获得整行。我在这里使用了200。选择对您的数据有意义的大小。您还可以使用malloc即时分配内存,并将fgets放入循环中,以便将整行读入缓冲区。