【问题标题】:Segmentation fault when trying to read file (C) [duplicate]尝试读取文件时出现分段错误(C)[重复]
【发布时间】:2018-06-27 00:34:12
【问题描述】:

我正在尝试用 C 语言编写一个程序,该程序将逐个字符地遍历文件并将它们打印到控制台。但是,在运行下面的代码时,我收到错误Segmentation fault: 11。我的代码中的问题在哪里?

void readFile(char fileName);

int main(const int argc, char *argv[])
{
    int status = 0;

    for (int i = 1; i < argc; i++) {
        readFile(*argv[i]);
    }

    exit(status);
}

void readFile(char fileName)
{
    FILE* file;
    char c;

    file = fopen(&fileName, "r");

    do {
        c = getc(file);
        printf("%c", c);
        if (!isalpha(c)) {
            printf("\n");
        }
    } while (c != EOF);

    fclose(file);
}

【问题讨论】:

  • 调试器会告诉你哪一行有段错误。
  • 你的readFile逻辑错误:你在检查是否为EOF之前使用c,而c的类型错误(必须是int)。

标签: c file command-line segmentation-fault


【解决方案1】:

readFile的签名有误。

void readFile(char fileName);

readFile 是需要单个字符而不是字符串的函数。 *argv[i] 返回argv[i]指向的字符串的第一个字母。

void readFile(const char *fileName)
{
    FILE* file;
    int c; // getc returns an int

    file = fopen(fileName, "r");

    // always check for errors
    if(file == NULL)
        return;

    do {
        c = getc(file);
        printf("%c", c);
        if (!isalpha(c)) {
            printf("\n");
        }
    } while (c != EOF);

    fclose(file); // do not forget to close your streams.
}

注意这里你的do-while-loop 是错误的,因为你应该检查首先 c 是否为 EOF。如果不是,那么您可以打印它。应该是:

while((c = getc(file)) != EOF)
{
    putc(c, stdout); // equivalent to printf("%c", c)
    if(!isalpha(c))
        puts("");  // equivalent to printf("\n");
}

那么你可以这样称呼它:

int main(const int argc, char *argv[])
{
    int status = 0;

    for (int i = 1; i < argc; i++) {
        readFile(argv[i]);
    }

    exit(status);
}

还要注意getc 返回的是int,而不是char,所以c 变量必须是 一个int

man fgets

#include <stdio.h>

int getc(FILE *stream);

描述

getc() 等价于fgetc(),不同之处在于它可以实现为不止一次计算流的宏。

返回值

fgetc()getc()getchar() 将字符读取为 unsigned char 转换为 intEOF 在文件末尾或错误。

另见this explanation

【讨论】:

  • do-while 循环应该是一个while 循环(在打印c 之前检查EOF)。
  • 我有 #include &lt;ctype.h&gt;,我相信它解决了 int 问题。
  • @melpomene 我添加了fclose,我错过了。
  • 通常char c的失败模式是相反的:字符255被误认为EOF(因为char通常是有符号类型)。
  • @melpomene 我添加了关于 do-while 循环的注释,感谢您的反馈。关于EOFchar 核对:是EOF 被提升为signed char 吗?
【解决方案2】:

你在很多方面都做错了。您传递了 i-th 参数的 0th 字符。你想传递整个字符串。你需要通过char*

readFile(argv[i]);

您将把这个char* 直接传递给fopen,然后检查它的返回值。循环可以很简单

while( (c=getc(file)) != EOF){

}
...
fclose(file);

您必须使用int c 而不是char c 确保它可以保存getc 返回的所有值。

【讨论】:

    猜你喜欢
    • 2018-05-01
    • 2013-10-20
    • 2019-07-07
    • 1970-01-01
    • 2022-10-04
    • 2019-06-08
    • 2019-03-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多