c - 为什么声明结构指针会阻止文件读取?
问题描述
我现在正在尝试学习 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 进行编译,没有任何选项。
解决方案
这是您提到的代码中的一些观察结果。
正如@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);
推荐阅读
- c# - 未找到 Microsoft.NetCore.App 或 Microsoft.AspNetCore.App 的指定版本
- node.js - NPM:运行并行脚本时如何读取进程参数?
- docker - 在单个 docker 中连接服务
- shell - system() 产生不一致的结果
- javascript - 删除数组中的重复对象,仅基于对象中的一个值
- python - Python Def函数结果,在Python中调用一个Class函数
- elasticsearch - 配置基于大小索引生命周期管理的删除索引策略弹性搜索
- php - 如何使用 codeigniter 3 创建验证邮件
- psd2 - Xs2a 支持自定义银行功能(银行特定支付、银行特定账户信息)
- python - Swift 接收字符串并在 Python 中运行