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

树莓派3裸机C编程中selectedTextColor与selectedBgColor为何无值?

问题分析与修复方案

你的代码中selectedTextColor和selectedBgColor出现无值(野指针状态),导致终端颜色无法修改,核心问题集中在变量初始化缺失、输入逻辑覆盖不全以及数组遍历存在隐患这几点。

具体问题点

  • 指针未初始化:selectedTextColor和selectedBgColor是未初始化的指针,若输入未触发赋值逻辑(比如直接回车、输入格式不符合预期),后续调用my_strcmp会访问非法内存,甚至引发程序崩溃。
  • 输入逻辑未覆盖结尾场景:当前仅在遇到空格时才调用get_color_code赋值,若用户输入-t red后直接回车(无空格),这部分输入不会被处理,变量依然处于无值状态。
  • 数组遍历终止条件不安全:用"none"作为数组终止项,若遍历到数组边界仍未匹配到"none",会导致数组越界访问。

修复后的完整代码

typedef struct color {
    const char *colorName;
    const char *textColor;
    const char *bgColor;
} color;

// 改用NULL作为数组终止标记,避免越界风险
color color_values[] = {
    {"black", "30", "40"},
    {"red", "31", "41"},
    {"green", "32", "42"},
    {"yellow", "33", "43"},
    {"blue", "34", "44"},
    {"purple", "35", "45"},
    {"cyan", "36", "46"},
    {"white", "37", "47"},
    {NULL, NULL, NULL}
};

// 根据颜色名称获取对应的终端颜色码
const char* get_color_code(const char* color, int is_background) {
    // 以NULL判断数组结尾,遍历更安全
    for (int i = 0; color_values[i].colorName != NULL; i++) {
        if (my_strcmp(color_values[i].colorName, color) == 0) {
            return is_background ? color_values[i].bgColor : color_values[i].textColor;
        }
    }
    return "0";  // 未匹配到则返回默认重置色
}

void selectColor() {
    char colorInput[MAX_CMD_SIZE];
    int inputIndex = 0; // 初始化输入索引
    char command = 0;   // 初始化命令标记
    // 初始化指针为默认值,彻底避免野指针
    const char *selectedTextColor = "0";
    const char *selectedBgColor = "0";
    char c;

    while ((c = uart_getc()) != '\n') {
        uart_sendc(c); // 回显输入字符到终端

        if (c == ' ') {
            if (command == 't') {
                colorInput[inputIndex] = '\0';
                selectedTextColor = get_color_code(colorInput, 0);
            } else if (command == 'b') {
                colorInput[inputIndex] = '\0';
                selectedBgColor = get_color_code(colorInput, 1);
            }
            command = 0;
            inputIndex = 0;
        } else if (c == '-') {
            c = uart_getc(); // 读取后续的命令标识t/b
            uart_sendc(c);
            if (c == 't' || c == 'b') {
                command = c;
                inputIndex = 0; // 切换命令时重置输入索引
            }
            continue;
        } else if (command) {
            // 防止缓冲区溢出,预留空间存储结束符
            if (inputIndex < MAX_CMD_SIZE - 1) {
                colorInput[inputIndex++] = c;
            }
        }
    }

    // 循环结束后处理最后一次未完成的输入(比如直接回车的情况)
    if (command == 't') {
        colorInput[inputIndex] = '\0';
        selectedTextColor = get_color_code(colorInput, 0);
    } else if (command == 'b') {
        colorInput[inputIndex] = '\0';
        selectedBgColor = get_color_code(colorInput, 1);
    }

    if (my_strcmp(selectedTextColor, "0") != 0) {
        uart_puts("\033[");
        uart_puts(selectedTextColor);
        uart_puts("m");
    }
    if (my_strcmp(selectedBgColor, "0") != 0) {
        uart_puts("\033[");
        uart_puts(selectedBgColor);
        uart_puts("m");
    }
}

关键修复说明

  1. 变量初始化:将selectedTextColor、selectedBgColor初始化为默认重置色"0",inputIndex和command也设置初始值,彻底消除野指针风险。
  2. 补充结尾输入处理:在while循环结束后,检查是否存在未处理的命令,对最后一次输入进行赋值,覆盖用户直接回车的场景。
  3. 安全遍历数组:把数组终止项改为{NULL, NULL, NULL},遍历用color_values[i].colorName != NULL判断,避免数组越界访问。
  4. 缓冲区溢出防护:写入colorInput时判断索引是否小于缓冲区最大容量减一,防止溢出破坏内存。

内容的提问来源于stack exchange,提问作者L.T.A

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 07:54:58