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

使用getopt()解析多参数遇阻:进制转换计算器开发求助

十进制转进制计算器的命令行参数问题解决方案

问题1:处理单个选项后的多个参数

核心问题是未遍历getopt处理完选项后剩余的所有参数。getopt解析完选项后,未被处理的参数从argv[optind]开始,只需循环遍历这部分参数即可实现批量转换。

问题2:触发print_usage的场景处理

需要覆盖三类异常情况:

  1. 未指定任何有效选项(如./a.out 1234)
  2. 输入未知选项(如./a.out -x -p 1234)
  3. 指定了选项但未提供待转换的数字参数

通过检查getopt返回值(遇到未知选项返回?)、转换函数指针是否为NULL(未选中有效选项),以及optind是否等于argc(无数字参数)来触发用法提示。

完整示例代码

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

void dec_to_bin(long num) {
    // 二进制转换实现
    printf("%ld -> 0b", num);
    if (num == 0) {
        printf("0\n");
        return;
    }
    char bin[64] = {0};
    int idx = 62;
    while (num > 0) {
        bin[idx--] = (num % 2) + '0';
        num /= 2;
    }
    printf("%s\n", &bin[idx+1]);
}

void dec_to_hex(long num) {
    // 十六进制转换实现
    printf("%ld -> 0x%lx\n", num, num);
}

void print_usage(const char *prog_name) {
    fprintf(stderr, "Usage: %s [-x|-b] decimal_numbers...\n", prog_name);
    fprintf(stderr, "Options:\n");
    fprintf(stderr, "  -x    Convert decimal numbers to hexadecimal\n");
    fprintf(stderr, "  -b    Convert decimal numbers to binary\n");
    exit(EXIT_FAILURE);
}

int main(int argc, char *argv[]) {
    int opt;
    void (*convert_func)(long) = NULL;

    // 解析命令行选项
    while ((opt = getopt(argc, argv, "xb")) != -1) {
        switch (opt) {
            case 'x':
                convert_func = dec_to_hex;
                break;
            case 'b':
                convert_func = dec_to_bin;
                break;
            case '?':
                // 未知选项触发用法提示
                print_usage(argv[0]);
            default:
                print_usage(argv[0]);
        }
    }

    // 未指定有效选项触发提示
    if (convert_func == NULL) {
        print_usage(argv[0]);
    }

    // 批量处理所有待转换数字
    for (; optind < argc; optind++) {
        char *endptr;
        errno = 0;
        long num = strtol(argv[optind], &endptr, 10);
        
        // 校验数字合法性
        if (errno != 0 || endptr == argv[optind] || *endptr != '\0') {
            fprintf(stderr, "Error: '%s' is not a valid decimal number\n", argv[optind]);
            print_usage(argv[0]);
        }

        convert_func(num);
    }

    // 指定选项但无数字参数触发提示
    if (optind == argc) {
        fprintf(stderr, "Error: No decimal numbers provided\n");
        print_usage(argv[0]);
    }

    return EXIT_SUCCESS;
}

关键细节说明

  1. 用strtol替代atoi:能精准处理非法数字输入(非数字字符、数值溢出等场景)
  2. 函数指针简化逻辑:避免批量转换时重复判断选项类型
  3. 全覆盖异常场景:包含无选项、错误选项、无数字参数、非法数字等所有异常情况

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 22:55:12