【问题标题】:Using fopen() in another function在另一个函数中使用 fopen()
【发布时间】:2014-05-29 08:14:52
【问题描述】:

我正在尝试使用 C 语言处理文件。我想要一个函数来接收指向 FILE 的指针,询问要读取的文件的名称,并将其初始化以供读取。所以,我是这样写的:

void initFileReading(FILE* fp){
    char dic[40];
    printf("Dictionary file: ");
    scanf("%40[^\n]", dic);

    fp = fopen(dic, "r");
}

int main(){
    int diff, i, nWords, Len;
    char str[16];
    FILE* fp;

    initFileReading(fp);

    fscanf(fp, "%s", str);
    printf("%s", str);

    return 0;
}

当我尝试运行它时,我得到一个 SegFault。但是,如果我将函数中的内容放在 main 中,它运行良好。谁能给我一点见解?

谢谢。

【问题讨论】:

  • 请注意,虽然使用"%40[^\n]" 是(大多数情况下)一个好主意,但您必须在格式字符串中指定不带终止空值的长度,因此请使用"%39[^\n]"char str[41]; 以避免1 字节覆盖。 (是的,它不符合现代习语,但改变它会破坏很多代码,所以它没有改变。)
  • @JonathanLeffler 您似乎是一位经验丰富的 C 程序员,为什么不直接提出正确的解决方案 (fgets()) 来代替?
  • @user3477950:两个原因(值得商榷)。 (1)问题使用scanf(),这不是自动错误的,指出正确使用scanf()的微妙之处是帮助SO的重要部分,(2)使用fgets()并不是一个简单的替代品,因为你必须准备好处理输入字符串中的换行符,并准备好处理它的缺失(表明输入字符串 -- 文件名 -- 比允许的空间长)。 [...然后是“我为什么没想到?”...]

标签: c fopen


【解决方案1】:

分配给fp 不会修改调用函数中的变量——你只有一个指向文件的指针,而不是指向文件指针的指针。但是要修改调用函数中的指针,您需要这样做:

void initFileReading(FILE** fpp){
    char dic[40];
    printf("Dictionary file: ");
    scanf("%39[^\n]", dic);

    *fpp = fopen(dic, "r");
}

int main(){
    int diff, i, nWords, Len;
    char str[16];
    FILE* fp;

    initFileReading(&fp);

    fscanf(fp, "%s", str);
    printf("%s", str);

    return 0;
}

但是,只需 return 新打开的文件会更简洁:

FILE* initFileReading(){
    char dic[40];
    printf("Dictionary file: ");
    scanf("%39[^\n]", dic);

    return fopen(dic, "r");
}

在您的主要功能中,您可以简单地使用fp = initFileReading();

【讨论】:

  • 哦,我明白了。非常感谢。
【解决方案2】:

作为参数传递给函数的值被复制到函数内部的局部变量中。因此,“initFileReading”中的“fp”是一个局部变量,当您将 fopen 的返回值分配给它时,您并没有将该值分配给“main”中的“fp”。如果你想这样做,'initFileReading' 必须接受一个指向 FILE* 的指针(一个内存地址)。在这种情况下,内存地址值也会被复制,但是当您修改它指向的内存时,您正在修改 main 中的“fp”。

函数会是这样的:

void initFileReading(FILE** fp){
    char dic[40];
    printf("Dictionary file: ");
    scanf("%40[^\n]", dic);

     *fp = fopen(dic, "r");
}

你叫它

initFileReading(&fp);

其中 & 是地址运算符,它返回该变量的地址。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多