为什么scanf会在读取字符串时崩溃?

时间:2014-08-17 01:42:43

标签: c string scanf

这只是我编写的一个小程序,用于查找较大的问题。当我用scanf添加行时,一切都会改变。我知道它不安全,我读了关于printf错误的其他线程,这些错误暗示了其他功能。除了cin之外什么都没关系。顺便说一句,我没有选择来自我老师的“消息”的类型定义,所以我无法改变它们。

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


char message1 [] = "amfdalkfaklmdklfamd.";
char message2 [] = "fnmakajkkjlkjs.";
char initializer [] = ".";
char* com;
char* word;
int main()
{   
    com = initializer;
    int i = 1;
    while (i !=4)
    {   
        printf ("%s \n", com);
        scanf("%s",word);
        i++;
    };  
    return 0;
}

问题:在一次迭代后,程序退出,没有打印任何内容。

3 个答案:

答案 0 :(得分:6)

scanf崩溃的原因是缓冲区未初始化:word尚未分配值,因此无法指向。

您可以通过为缓冲区分配一些内存并将scanf限制为特定数量的字符来修复它,如下所示:

char word[20];
...
scanf("%19s", word);

请注意,%s之间的数字(表示字符串中的最大字符数)比实际缓冲区的长度少1。这是因为null终结符,这是C字符串所必需的。

答案 1 :(得分:1)

com是一个指针,其值是文字字符串initializer的地址。文字字符串包含在只读存储区中,但scanf函数会尝试到给定的地址,这是一种访问冲突并导致操作系统杀死你的过程,因此你看到的崩溃。

将您的scanf代码更改为与此类似,请注意%s占位符中添加的宽度限制,以及使用scanf_s版本以确保没有缓冲区溢出

static int const BufferLength = 2048; // 2KiB should be sufficient
char* buffer = calloc( BufferLength , 1 ); 
if( buffer == null ) exit(1);
int fieldCount = scanf_s("%2047s", buffer, BufferLength );
if( fieldCount == 1 ) {
    // do stuff with `buffer`
}
free( buffer );

请注意,calloc在返回之前将内存归零,这意味着buffer可以直接作为以null结尾的字符串,而使用malloc分配的字符串则不能(除非您自己将其归零) )。

答案 2 :(得分:0)

word没有与之关联的记忆。

char* word;
scanf("%s",word);

可以使用

char word[100];
word[0] = '\0';
scanf("%99s",word);

如果可用,请使用getline()

虽然不是标准C,getline()将动态地为任意长的用户输入分配内存。

char *line = NULL;
size_t len = 0;
ssize_t read;
while ((read = getline(&line, &len, stdin)) != -1) {
  printf("%s", line);
}
free(line);

Linux Programmer's Manual GETLINE(3)