You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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;
}

关键修复点说明

  1. 命令行参数支持:通过argv[1]获取输入文件名,替代硬编码路径,提升灵活性
  2. 整行读取:使用fgets()替代fscanf("%s"),可以完整读取包含空格的行
  3. 行存储与排序:用动态数组存储所有行,借助qsort()和自定义比较函数实现按行长度降序排序(对应预期顺序2-3-5-1-4)
  4. 统一输出逻辑:先读取所有行并排序,再遍历输出到命令行和文件,避免文件指针位置问题
  5. 资源管理:动态内存分配后及时释放,文件操作完成后关闭文件句柄,避免资源泄漏

内容的提问来源于stack exchange,提问作者JohnDoe12

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 09:10:33