【问题标题】:Reading from stdin using fgets()使用 fgets() 从标准输入读取
【发布时间】:2016-11-03 22:03:28
【问题描述】:

我是 C 编程新手,我目前正在尝试使用 fgets() 从标准输入读取一行,但我在内存分配方面遇到了问题,因为我使用 char* 指向字符串 I想读。当我执行该文件时,它会报告分段错误。

这是我正在使用的功能:

char *read_line(char *line){
    printf("%s",PROMPT);
    line = (char*)malloc(sizeof(char)*500);
    fgets(line,sizeof(line),stdin);
    printf("%s","pasa el fgets");
    return line;
}

还有我的主要:

void main(){
    char line0;
    char *line=&line0;
    while(read_line(line)){
        execute_line(line);
    }
}

【问题讨论】:

  • char line0; char *line=&line0; 现在line 指向长度为1 的char 缓冲区。如果您的行长度超过1 个字节,您将超出缓冲区。与其只是在编译之前把代码塞进去,不如试着真正了解它在做什么。我会推荐 C 教程、书籍或课程。
  • 在这么少的代码行中有这么多错误;-)
  • sizeof(line) 是指针的大小,而不是分配内存的大小。
  • 1) fgets(line,sizeof(line),stdin); --> fgets(line, 500, stdin); 2) while(read_line(line)){ --> while(line = read_line(line)){ //需要空闲(行);并打破循环
  • @JonathonReinhart 所以你建议在那里使用 malloc?

标签: c pointers segmentation-fault malloc fgets


【解决方案1】:

主要错误是将指针line 传递给函数read_line(按值)并尝试在该函数中对其进行修改。

read_line 分配内存并实际创建指针值。所以应该可以改变mainline的值:

char *read_line(char **line){
    ...
    *line = malloc(500);
    fgets(*line, 500, stdin);
    ...
    return *line;
}

int main(void) {
    char *line;
    while(read_line(&line)){
        ...
    }

}

或者,您使用read_line 的返回值来修改mainline。在这种情况下,您根本不需要该参数:

char *read_line(void) {
    char *line;
    ...
    line = malloc(500);
    fgets(line, 500, stdin);
    ... 
    return line;
}

int main(void) {
    char *line;
    while(line = read_line()){
        ...
    }
}

其他错误(由 Jonathon Reinhart 指出)和备注:

  1. sizeof 不适用于指针(数组衰减为指针)。
  2. malloc很多字符串line但你没有free他们。
  3. sizeof(char) 始终为 1。
  4. 有些人(我也是)认为应该避免转换malloc 的结果。

【讨论】: