C语言求助:基于命令行参数实现文本文件按行长度排序
C语言文本行排序程序问题修复与实现
需求说明
编写C语言程序,通过命令行参数指定文本文件,读取文件内容后按行长度排序,同时将结果输出到命令行和输出文件。
测试用例文本
1. hello world 2. john doe at the bay watch 3. Great Heavens 4. altair 5. Jim and Jamy
现有代码(source.c)
int main(void) { FILE* fread = fopen("C:\\Users\\Peter\\desktop\\input.txt", "r"); FILE* fwrite = fopen("C:\\Users\\Peter\\desktop\\output.txt", "w"); if (fread == NULL || fwrite == NULL) { printf("One file wouldn't open!\n"); return -1; } //(1.) this copies the text from input.txt to output.txt char c; while ((c = fgetc(fread)) != EOF) { fputc(c, fwrite); } //(2.) this pastes the text from input.txt into the command-line char line[1000] = ""; while (fscanf(fread, "%s", line) == 1) { printf("%s\n", line); } fclose(fread); fclose(fwrite); }
存在的问题
- 文件复制与命令行输出仅能正常执行其一:文件指针读取到EOF后未重置,后续读取无法获取内容
- 命令行输出拆分内容:
fscanf("%s")以空格为分隔符,无法读取整行 - 未实现按行长度排序:缺少行存储与排序逻辑
- 无法同时输出排序结果到命令行和文件:原逻辑未先排序再统一输出
修复后完整代码
#include <stdio.h> #include <stdlib.h> #include <string.h> // 自定义排序规则:按行长度降序排列 int compare_lines(const void *a, const void *b) { const char *line1 = *(const char **)a; const char *line2 = *(const char **)b; int len1 = strlen(line1); int len2 = strlen(line2); // 降序排序,若要升序则返回 len1 - len2 return len2 - len1; } int main(int argc, char *argv[]) { // 检查命令行参数 if (argc != 2) { printf("用法: %s <输入文件名>\n", argv[0]); return 1; } FILE *input_file = fopen(argv[1], "r"); FILE *output_file = fopen("output.txt", "w"); if (input_file == NULL || output_file == NULL) { perror("文件打开失败"); return 1; } // 存储所有行的数组,初始分配10个行的空间 char **lines = malloc(10 * sizeof(char *)); if (lines == NULL) { perror("内存分配失败"); fclose(input_file); fclose(output_file); return 1; } int line_count = 0; int max_lines = 10; char buffer[1000]; // 逐行读取文件内容 while (fgets(buffer, sizeof(buffer), input_file) != NULL) { // 去掉换行符(如果存在) size_t len = strlen(buffer); if (len > 0 && buffer[len-1] == '\n') { buffer[len-1] = '\0'; } // 动态扩容数组 if (line_count >= max_lines) { max_lines *= 2; char **temp = realloc(lines, max_lines * sizeof(char *)); if (temp == NULL) { perror("内存扩容失败"); // 释放已分配的行内存 for (int i = 0; i < line_count; i++) { free(lines[i]); } free(lines); fclose(input_file); fclose(output_file); return 1; } lines = temp; } // 复制行内容到动态分配的内存 lines[line_count] = malloc(strlen(buffer) + 1); if (lines[line_count] == NULL) { perror("行内存分配失败"); // 清理资源 for (int i = 0; i < line_count; i++) { free(lines[i]); } free(lines); fclose(input_file); fclose(output_file); return 1; } strcpy(lines[line_count], buffer); line_count++; } // 按行长度排序 qsort(lines, line_count, sizeof(char *), compare_lines); // 输出排序后的内容到命令行和文件 for (int i = 0; i < line_count; i++) { printf("%s\n", lines[i]); fputs(lines[i], output_file); fputs("\n", output_file); } // 清理资源 for (int i = 0; i < line_count; i++) { free(lines[i]); } free(lines); fclose(input_file); fclose(output_file); return 0; }
关键修复点说明
- 命令行参数支持:通过
argv[1]获取输入文件名,替代硬编码路径,提升灵活性 - 整行读取:使用
fgets()替代fscanf("%s"),可以完整读取包含空格的行 - 行存储与排序:用动态数组存储所有行,借助
qsort()和自定义比较函数实现按行长度降序排序(对应预期顺序2-3-5-1-4) - 统一输出逻辑:先读取所有行并排序,再遍历输出到命令行和文件,避免文件指针位置问题
- 资源管理:动态内存分配后及时释放,文件操作完成后关闭文件句柄,避免资源泄漏
内容的提问来源于stack exchange,提问作者JohnDoe12
相关产品推荐
相关产品推荐

