gcc编译得非常好,但是一旦scanf接受了一个字符串就会出现故障。我有点不知所措。这是代码。
char *line[256];
void *mainThread()
{
while (*line != "quit") {
scanf("%s", *line);
printf("%s", *line);
}
return;
}
有什么关于scanf我在这里不明白吗?
答案 0 :(得分:5)
首先,您要为字符分配指针数组,而不是 char 数组:
char *line[256]; /* allocates 256 pointers to a character -
(pointers are initialized to NULL) */
您需要分配一个字符数组:
char line[256]; /* allocates 256 characters */
其次,您需要使用strcmp
来比较字符串 - 与!=
,您正在比较line[0]
中存储的指针(地址)(与{{1}相同使用指向字符串文字*line
的指针,它们总是不同的。
您可以使用以下sscce作为起点:
"quit"
一些补充说明:
#include <string.h>
#include <stdio.h>
char line[256];
int main()
{
while (strcmp(line, "quit") != 0) {
scanf("%s", line);
printf("%s", line);
}
return 0;
}
指针,但您没有返回任何内容(使用void*
没有参数)。然后,您应该将其声明为return
。void
来读取输入,因为它可能会读取比分配的字符更多的字符,从而导致缓冲区溢出。请改用scanf()
。另请参阅Disadvantages of scanf。fgets()
进行编译。答案 1 :(得分:2)
声明全局变量时,它们被初始化为零。当你声明一个指向char
的指针数组(而不是我认为你真正想要的char
数组)时,你有一个256个NULL
指针的数组。
在数组上使用解引用运算符*
与执行例如array[0]
,这意味着作为scanf
和printf
的参数,您正在传递line[0]
,如上所述,它是NULL
指针。取消引用NULL
指针(如scanf
和printf
将会这样做)是未定义行为的情况,几乎总是会导致崩溃。
答案 2 :(得分:1)
它正在编译,因为您的程序在语法上是正确的。但是,它有严重的语义错误,由于段错误而显示为程序崩溃。全局数组line
被初始化为零,作为任何全局变量。因为line
是一个指针数组(不是一个预期的字符数组),所以零被解释为空指针NULL
。 *line
与line[0]
相同,字符串文字"quit"
计算为指向其第一个元素的指针。因此while
条件与
while(NULL != "quit") // always true
接下来,scanf("%s", *line);
尝试将输入字符串写入line[0]
指向的缓冲区,即NULL
- 一个不等于任何内存位置地址的值。这将导致段错误并导致程序崩溃。
您的代码段中还有其他错误。让我们一个接一个。
char *line[256];
上述语句定义了一个256个指向字符的数组line
,即其类型为char *[256]
。你需要的是一个字符数组 -
char line[256];
您无法比较C
中的数组。你可以做的是逐个元素地比较它们。对于字符串,您应该使用标准库函数strcmp
。另请注意,格式字符串%s
中的scanf
转换说明符从stdin
读取一个字符串,并将其写入下一个参数指向的缓冲区。它在结尾处放置一个终止空字节,但如果输入的字符串太大而无法保存缓冲区,则不会检查缓冲区溢出。这将导致未定义的行为,并且很可能由于非法内存访问而导致段错误。您应该通过在格式字符串中指定最大字段宽度来防止缓冲区溢出。
void *mainThread();
上面的函数声明意味着mainThread
是一个返回void *
类型指针的函数,并且取一个未指定但固定数量和类型的参数,因为空括号表示没有提供有关参数列表的信息。您应该在参数列表中编写void
以表示该函数不带参数。另请注意,如果使用函数的返回值,函数中的空返回语句将导致未定义的行为,因为您没有返回任何内容,而是在函数的返回地址中使用垃圾值。假设您要返回字符串,则应将其定义为 -
char line[256];
char *mainThread(void) {
while(strcmp(line, "quit") != 0) {
scanf("%255s", line); // -1 for the terminating null byte
printf("%s", line);
}
return line;
}