如何在C语言中将文件读取的数据以字符串形式存储到数组?附错误代码
问题分析与代码修正
咱们先拆解你代码里的几个关键问题,这些是导致程序出错的核心原因:
- 文件名存储错误:你用
char name存文件名,这只是单个字符,根本装不下完整文件名,得换成足够大的字符数组,比如char name[256](能容纳大多数系统的文件名)。 scanf_s参数错误:用字符数组存文件名时,scanf_s直接传数组名name就行(数组名本身就是首地址),不需要加&;另外scanf_s需要传入缓冲区大小参数,防止溢出。- 文件打开逻辑混乱:你先写了
if(file !=fopen(&name,"r")),但此时file未初始化,而且fopen的返回值没赋值给file就判断,完全不符合逻辑。正确做法是先调用fopen赋值给file,再判断是否为NULL(表示打开失败)。另外你后面重复调用fopen,会导致第一次打开的文件句柄泄漏,浪费系统资源。 - 字符串读取方式错误:
fscanf(file, "%s", &character[i])里,%s是读取完整字符串(直到空白字符),但你传的是单个字符的地址&character[i],这样读取的字符串会直接覆盖数组后续内存,造成越界,大概率导致程序崩溃或乱码。 - 循环逻辑冗余:外层
for循环和内层do-while循环重复控制读取流程,会导致读取到文件末尾后还执行不必要的循环。
修正方案1:读取文件中的所有单词(按空白分隔)到字符串数组
如果你想把文件里的每个单词作为独立字符串,存储到二维字符数组中,可以用下面的代码:
#include <stdio.h> #include <stdlib.h> #define MAX_WORDS 100 // 最多存储100个单词 #define MAX_WORD_LEN 30 // 每个单词最长30个字符 int main(){ FILE *file; char name[256]; // 用足够大的数组存储文件名 char words[MAX_WORDS][MAX_WORD_LEN]; // 二维数组存储多个字符串 int word_count = 0; printf("Please enter a file name: "); // scanf_s读取文件名,传入缓冲区大小避免溢出 scanf_s("%s", name, (unsigned)_countof(name)); // 打开文件并判断是否成功 file = fopen(name, "r"); if(file == NULL){ printf("File could not be opened.\n"); return EXIT_FAILURE; // 打开失败直接退出程序 } // 读取每个单词到二维数组,直到文件末尾或达到最大单词数 while(word_count < MAX_WORDS && fscanf(file, "%s", words[word_count]) != EOF){ word_count++; } // 输出验证读取的内容 printf("\nRead %d words from file:\n", word_count); for(int i = 0; i < word_count; i++){ printf("%s\n", words[i]); } fclose(file); // 关闭文件,释放资源 return EXIT_SUCCESS; }
修正方案2:读取整个文件内容到单个字符串数组
如果你想把整个文件的内容(包括换行、空格)作为完整字符串存储,可以这样实现:
#include <stdio.h> #include <stdlib.h> int main(){ FILE *file; char name[256]; char *content = NULL; long file_size; printf("Please enter a file name: "); scanf_s("%s", name, (unsigned)_countof(name)); file = fopen(name, "r"); if(file == NULL){ printf("File could not be opened.\n"); return EXIT_FAILURE; } // 移动文件指针到末尾,获取文件大小 fseek(file, 0, SEEK_END); file_size = ftell(file); fseek(file, 0, SEEK_SET); // 移回文件开头 // 分配内存(+1是为了存储字符串结束符'\0') content = (char*)malloc(file_size + 1); if(content == NULL){ printf("Memory allocation failed.\n"); fclose(file); return EXIT_FAILURE; } // 读取整个文件内容到字符串 fread(content, 1, file_size, file); content[file_size] = '\0'; // 手动添加字符串结束符 // 输出验证 printf("\nFile content:\n%s", content); // 释放动态分配的内存和关闭文件 free(content); fclose(file); return EXIT_SUCCESS; }
关键注意事项
- 始终要检查
fopen、malloc等函数的返回值,避免空指针操作导致程序崩溃。 - 使用
scanf_s时必须传入缓冲区大小参数(比如上面的(unsigned)_countof(name)),这是scanf_s的安全要求,防止缓冲区溢出。 - 操作完文件后一定要调用
fclose关闭文件句柄,避免资源泄漏。 - 动态分配的内存(比如方案2里的
content),记得用free释放,防止内存泄漏。
内容的提问来源于stack exchange,提问作者Merve Çalık
相关产品推荐
相关产品推荐

