如何用C语言读取TXT文件随机选行并写入另一文件?
实现随机选取文本行并合并写入的C语言方案
你的思路完全正确——先把文件所有行加载到内存数组,再通过随机数选取元素合并写入,这是处理这类需求最高效的方式,尤其是文件规模不大的场景。下面给你具体实现步骤和代码:
核心步骤拆解
- 统计文件行数:先遍历源文件,统计总行数,为后续内存分配做准备
- 加载所有行到内存:用动态分配的字符串数组存储每一行内容
- 生成随机索引:初始化随机种子后,用
rand()生成合法的行索引 - 合并并写入结果:选取指定数量的行,拼接内容后写入目标文件
- 资源清理:关闭文件、释放动态分配的内存,避免泄漏
完整代码实现
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #define MAX_LINE_LEN 256 // 根据你的需求调整每行最大长度 int main() { // 1. 打开源文件和目标文件 FILE *src_file = fopen("source.txt", "r"); FILE *dest_file = fopen("Result.txt", "a"); // 用追加模式避免覆盖现有内容 if (!src_file || !dest_file) { perror("文件打开失败"); return 1; } // 2. 统计源文件行数 int line_count = 0; char buffer[MAX_LINE_LEN]; while (fgets(buffer, MAX_LINE_LEN, src_file) != NULL) { line_count++; } rewind(src_file); // 将文件指针重置到开头,准备读取内容 // 3. 动态分配存储行的数组 char **lines = malloc(line_count * sizeof(char*)); if (!lines) { perror("内存分配失败"); fclose(src_file); fclose(dest_file); return 1; } // 4. 将每行内容存入数组 for (int i = 0; i < line_count; i++) { lines[i] = malloc(MAX_LINE_LEN * sizeof(char)); if (!lines[i]) { perror("行内存分配失败"); // 释放已分配的内存 for (int j = 0; j < i; j++) free(lines[j]); free(lines); fclose(src_file); fclose(dest_file); return 1; } fgets(lines[i], MAX_LINE_LEN, src_file); // 去掉每行末尾的换行符(如果存在),方便合并 size_t len = strlen(lines[i]); if (len > 0 && lines[i][len-1] == '\n') { lines[i][len-1] = '\0'; } } // 5. 初始化随机种子 srand(time(NULL)); // 6. 随机选取2行合并(可根据需求修改选取数量) int select_count = 2; char merged_line[MAX_LINE_LEN * select_count] = ""; // 存储合并后的内容 for (int i = 0; i < select_count; i++) { int random_idx = rand() % line_count; // 生成0到line_count-1的随机索引 strcat(merged_line, lines[random_idx]); // 如果不是最后一行,可添加分隔符(比如空格) if (i != select_count - 1) { strcat(merged_line, " "); } } // 7. 将合并后的内容写入目标文件,添加换行 fprintf(dest_file, "%s\n", merged_line); // 8. 资源清理 for (int i = 0; i < line_count; i++) { free(lines[i]); } free(lines); fclose(src_file); fclose(dest_file); return 0; }
关于“读取非首行”的补充说明
如果不想把所有行加载到内存,要直接读取第N行,只能从文件开头逐行读取,直到第N行:
// 读取第n行(n从0开始计数) char* read_nth_line(FILE *file, int n) { rewind(file); char *line = malloc(MAX_LINE_LEN * sizeof(char)); if (!line) return NULL; for (int i = 0; i <= n; i++) { if (fgets(line, MAX_LINE_LEN, file) == NULL) { free(line); return NULL; // 行数不足 } } return line; }
但这种方法每次读取都要从头遍历,效率远不如先加载所有行到内存的方案,仅适合超大型文件(无法全部加载到内存)的场景。
内容的提问来源于stack exchange,提问作者fronow
相关产品推荐
相关产品推荐

