首页 > 解决方案 > 为什么声明结构指针会阻止文件读取?

问题描述

我现在正在尝试学习 C 中的文件处理,但我遇到了一些看似无关的问题。

我有一个包含一些用户名的文本文件,我正在尝试打开文件以读取并打印文件中的第一个用户名。当我运行以下代码和文件时,它工作正常:

文件读取.c

#include <stdio.h>
#include <stdlib.h>

struct list_node {
    char *value;
    struct list_node *next;
};

int main(int argc, char *argv[]) {
    if (argc <= 1) {
        printf("Usage: a.out <file containing usernames>\n");
        exit(EXIT_FAILURE);
    }
    printf("%d\n", argc);
    printf("%s\n", *argv);
    printf("%s\n", *(argv+1));

    FILE *file = fopen(*(argv+1), "r");
    if (!file) {
        printf("Could not open file\n");
        exit(EXIT_FAILURE);
    }

    char *curr_username;
    int status = fscanf(file, "%s", curr_username);
    if (!curr_username || status == EOF) {
        printf("File is empty\n");
        exit(EXIT_FAILURE);
    } else {
        printf("first username was: %s\n", curr_username);
    }
    struct list_node first_node = {curr_username, NULL};
    /*struct list_node *last_node = &first_node;*/

    fclose(file);

    exit(EXIT_SUCCESS);
}

用户名.txt

me@host
you@host
him@host
her@host

用法

./a.out usernames.txt


当我按照“用法”中所示运行程序时,它会打印以下内容:

2
./a.out
usernames.txt
first username was: me@host


在代码片段中,您可以看到注释掉的一行应该声明一个结构指针。我的下一步是将所有用户名读入一个简单的链表。因此,我使用指针将前一项存储在列表中。

但是,当我取消注释这一行并重新编译并运行程序时,输出将变为:

2
./a.out
usernames.txt
File is empty


这里发生了什么?这种优化是在做我不想要的事情,还是我在某处触发了某种未定义的行为,或者完全是其他事情?

我正在使用 GCC 版本 4.1.2 进行编译,没有任何选项。

标签: c

解决方案


这是您提到的代码中的一些观察结果。

  • 正如@EugeneSh 在声明中的评论中指出的那样

       fscanf(file, "%s", curr_username);
    

    您正在读取file并存储curr_username未初始化或没有有效内存要存储的内容,因此这会导致代码中出现未定义的行为。

    curr_username为& 然后使用扫描分配内存fscanf()。例如

    char *curr_username = malloc(MAX_STR_SIZE); /* define the MAX_STR_SIZE */

    完成后,通过调用释放动态分配的内存free()以避免内存泄漏。例如

    free(curr_username);


推荐阅读