如何使用fgets和sscanf从文本文件读取数据存入结构体
从文本文件读取数据到自定义结构体的完整实现方案
看起来你已经搭好了基础框架,我来帮你补全并优化这个读取文件到结构体的实现。首先先把你给出的代码片段放出来:
#include <stdio.h> #include <stdlib.h> #include <string.h> #define SIZE 16 #define N 4 struct Prova { char nome[SIZE]; int num; }; // 你未完成的函数 void get_str(struct Prova * ptr){ FILE *f; int i = 0; if(!(f = fopen(PATH,"r+"))) { perror("Errore in apertura"); exit(0); } void * buffer = malloc(sizeof(s... }
现有代码的几个小问题
PATH宏没定义,得换成你实际的文件路径malloc这里其实没必要额外动态分配,直接用缓冲区存每行内容就行- 用
"r+"打开文件是读写模式,如果你只是读取数据,用"r"只读模式更安全,防止误改文件 - 缺少循环读取的核心逻辑,也没写
fclose,容易造成文件资源泄漏
修正后的完整代码
#include <stdio.h> #include <stdlib.h> #include <string.h> #define SIZE 16 #define N 4 // 替换成你的实际文件路径,比如当前目录下的dati.txt #define PATH "dati.txt" struct Prova { char nome[SIZE]; int num; }; void get_str(struct Prova *ptr) { FILE *f; int i = 0; // 用只读模式打开文件 if (!(f = fopen(PATH, "r"))) { perror("Errore in apertura"); exit(EXIT_FAILURE); // 用标准EXIT_FAILURE宏更规范 } // 定义缓冲区存每行内容,长度设大些避免截断 char buffer[100]; // 循环读取最多N行数据 while (i < N && fgets(buffer, sizeof(buffer), f) != NULL) { // 假设每行格式是"字符串 整数",比如"Mario 10" if (sscanf(buffer, "%s %d", ptr[i].nome, &ptr[i].num) == 2) { i++; // 只有解析成功才计数 } else { fprintf(stderr, "Errore nella lettura della riga %d\n", i+1); } } // 务必关闭文件释放资源 fclose(f); } // 测试用主函数 int main() { struct Prova dati[N]; get_str(dati); // 打印读取到的数据验证结果 for (int i = 0; i < N; i++) { printf("Riga %d: Nome: %s, Numero: %d\n", i+1, dati[i].nome, dati[i].num); } return 0; }
关键要点说明
- 文件路径:把
PATH换成你的实际文件路径,比如"/home/you/documents/dati.txt"或者当前目录的"dati.txt" - 缓冲区设置:
buffer长度设为100是为了容纳大部分单行内容,避免fgets截断数据 - sscanf返回值检查:
sscanf会返回成功解析的参数个数,我们期望得到2个(字符串和整数),这样能过滤掉格式错误的行 - 资源释放:一定要调用
fclose(f),不然程序结束后可能会残留未释放的文件资源 - 错误提示:用
perror和fprintf打印错误信息,方便你调试时定位问题
文本文件格式要求
你的目标文件dati.txt需要每行对应一组数据,格式为[字符串] [整数],比如:
Mario 10 Luigi 20 Peach 30 Bowser 40
内容的提问来源于stack exchange,提问作者St3ve R0nix
相关产品推荐
相关产品推荐

