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

如何基于C语言命令行参数实现字符串唯一字符保留(去重)

问题描述

我希望实现字符串的字符去重功能,即每个字母仅保留一个(例如输入"send more money"时输出"sendmory")。现有以下两段C语言代码:

第一段代码(读取命令行参数)

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

int main(int argc, char *argv[])
{
    if (argc < 2)
    {
        printf("USAGE: <porgram name> <word sum>");
        return 1;
    }


    for (int i = 1; i < argc; i++)
    {
        printf("%s\n", argv[i]); //prints the command line input
    }

    return 0;
 }

我已编写好从标准输入读取字符串并完成去重的代码(如下所示),且结果正确,但不清楚如何修改为从命令行参数(argv)获取输入并实现相同功能,请问是需要将argv存入单独数组,还是直接对argv进行检查?具体该如何实现?

第二段代码(标准输入去重)

char str[100];
int i, j, k;
printf("\n Please Enter any String : ");
scanf("%s", str);
for(i = 0; i < strlen(str); i++) {
    for(j = i + 1; str[j] != '\0'; j++) {
        if(str[j] == str[i]) {
            for(k = j; str[k] != '\0'; k++) {
                str[k] = str[k + 1];
            }
        }
    }
}

解决方案

不需要单独将argv存入数组,你可以根据需求选择两种实现方式:

方式1:合并所有命令行参数后整体去重

适合将所有输入的单词合并为一个字符串再去重的场景(比如你给出的"send more money"示例):

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

int main(int argc, char *argv[])
{
    if (argc < 2)
    {
        printf("USAGE: %s <字符串1> <字符串2> ...\n", argv[0]);
        return 1;
    }

    // 计算所有参数的总长度,分配内存
    int total_len = 0;
    for (int i = 1; i < argc; i++) {
        total_len += strlen(argv[i]);
    }
    char *combined_str = (char*)malloc(total_len + 1);
    if (combined_str == NULL) {
        perror("内存分配失败");
        return 1;
    }
    combined_str[0] = '\0';

    // 拼接所有命令行参数
    for (int i = 1; i < argc; i++) {
        strcat(combined_str, argv[i]);
    }

    // 执行去重逻辑(修复原逻辑的小问题)
    int i, j, k;
    for(i = 0; i < strlen(combined_str); i++) {
        for(j = i + 1; combined_str[j] != '\0';) {
            if(combined_str[j] == combined_str[i]) {
                // 删除重复字符
                for(k = j; combined_str[k] != '\0'; k++) {
                    combined_str[k] = combined_str[k + 1];
                }
            } else {
                // 仅当当前字符不重复时才移动j
                j++;
            }
        }
    }

    printf("去重结果:%s\n", combined_str);
    free(combined_str);
    return 0;
}

方式2:逐个处理每个命令行参数的去重

如果需要分别对每个输入的单词去重并输出,可以将去重逻辑封装为函数,对每个argv元素单独处理:

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

// 封装去重函数
void remove_duplicates(char *str) {
    int i, j, k;
    for(i = 0; i < strlen(str); i++) {
        for(j = i + 1; str[j] != '\0';) {
            if(str[j] == str[i]) {
                for(k = j; str[k] != '\0'; k++) {
                    str[k] = str[k + 1];
                }
            } else {
                j++;
            }
        }
    }
}

int main(int argc, char *argv[])
{
    if (argc < 2)
    {
        printf("USAGE: %s <字符串1> <字符串2> ...\n", argv[0]);
        return 1;
    }

    for (int i = 1; i < argc; i++) {
        // argv指向只读内存,必须复制到可修改区域
        char *temp_str = strdup(argv[i]);
        if (temp_str == NULL) {
            perror("内存分配失败");
            return 1;
        }
        remove_duplicates(temp_str);
        printf("原字符串:%s → 去重后:%s\n", argv[i], temp_str);
        free(temp_str);
    }

    return 0;
}

关键注意点

  • 不能直接修改argv字符串:argv指向的是程序启动时的只读内存区域,强行修改会导致未定义行为,必须先复制到可写内存(如strdup分配的空间)。
  • 修复原去重逻辑的bug:原代码中删除字符后j仍会自增,会跳过下一个待检查的字符,调整为仅当字符不重复时才移动j即可解决。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 05:45:39