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

C语言使用argv按长度降序排序命令行单词输出异常求助

命令行参数按长度排序输出损坏的问题修复

核心问题

你代码中输出损坏的根本原因是直接修改了argv指向的只读字符串内容。argv数组中的每个char*指向的是程序启动时传入的字符串字面量,这类内存属于只读区域,用strcpy修改会触发未定义行为,导致输出乱码。同时你的冒泡排序循环边界存在小问题,会导致部分元素没被正确比较。

修复方案:交换指针而非修改字符串内容

最安全高效的做法是直接交换argv数组中的指针,不需要复制字符串内容——因为我们只需要调整参数的输出顺序,不需要修改参数本身。

修正后的代码

#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[]) {
    // 冒泡排序:按字符串长度降序,交换指针而非内容
    for (int i = 1; i < argc - 1; i++) {
        // 修正循环边界:避免遗漏最后一个待比较元素
        for (int j = 1; j < argc - i; j++) {
            if (strlen(argv[j]) < strlen(argv[j + 1])) {
                // 交换指针,安全且无内存操作
                char *temp = argv[j];
                argv[j] = argv[j + 1];
                argv[j + 1] = temp;
            }
        }
    }

    puts("");
    for (int i = 1; i < argc; i++) {
        printf("%s ", argv[i]);
    }
    puts(""); // 优化输出格式,避免终端提示符紧跟内容

    return 0;
}

测试结果

编译运行gcc test.c -o test && ./test I put this words,会得到正确输出:

words this put I 

可选方案:复制字符串到可写内存

如果后续需要修改参数内容,可以将每个参数复制到堆内存中再排序,记得最后释放内存避免泄漏:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main(int argc, char *argv[]) {
    // 分配指针数组存储字符串副本
    char **word_list = malloc(argc * sizeof(char*));
    if (!word_list) {
        perror("malloc failed");
        return 1;
    }

    // 复制每个命令行参数到堆内存
    for (int i = 1; i < argc; i++) {
        word_list[i] = strdup(argv[i]);
        if (!word_list[i]) {
            perror("strdup failed");
            // 出错时释放已分配的内存
            for (int k = 1; k < i; k++) free(word_list[k]);
            free(word_list);
            return 1;
        }
    }

    // 按长度降序排序字符串副本
    for (int i = 1; i < argc - 1; i++) {
        for (int j = 1; j < argc - i; j++) {
            if (strlen(word_list[j]) < strlen(word_list[j + 1])) {
                char *temp = word_list[j];
                word_list[j] = word_list[j + 1];
                word_list[j + 1] = temp;
            }
        }
    }

    // 输出结果
    puts("");
    for (int i = 1; i < argc; i++) {
        printf("%s ", word_list[i]);
        free(word_list[i]); // 释放单个字符串内存
    }
    puts("");
    free(word_list); // 释放指针数组内存

    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 18:23:23