十六进制颜色解析需先处理前缀与简写:若以'#'开头则截取后续,长度为3则每位展开为2位,非3或6位即非法;再用std::stoul(str, nullptr, 16)解析,捕获异常并校验值≤0xffffff;最后位运算提取rgb分量,封装为结构体返回。

十六进制颜色字符串格式不统一,先判断是 "#RRGGBB" 还是 "RRGGBB"
常见错误是直接用 std::stoul 解析带 # 的字符串,结果抛出 std::invalid_argument。C++ 标准库不自动跳过前导符号,必须手动处理。
实际场景中,输入可能是:"#ff0088"、"ff0088"、甚至 "#f08"(简写)。优先按完整 6 位处理,再考虑简写扩展。
- 先用
str[0] == '#'判断是否带前缀,有则取substr(1) - 若长度为 3(如
"f08"),需展开为"ff0088":每个字符重复一次 - 长度不是 3 或 6 时,直接视为非法,避免静默错误
用 std::stoul 转换时必须指定 base=16,且捕获异常
std::stoul("ff0088", nullptr, 16) 才能正确解析十六进制;省略第三个参数会按 base=10 解析,得到完全错误的数值(比如 "ff0088" 变成 0)。
即使格式看似合法,也可能因溢出或非法字符(如 'g')触发异常,不能假设输入安全。
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
- 务必用
try/catch包裹std::stoul,捕获std::invalid_argument和std::out_of_range - 转换后检查值是否 ≤ 0xffffff,防止意外高位数据(虽然 6 位 hex 最大就是 0xffffff,但防御性检查更稳)
- 推荐用
unsigned long接收,避免符号扩展问题
拆解 RGB 分量:位运算比除法更直观可靠
拿到 0xff0088 这样的整数后,用位运算提取分量比反复除以 256 更高效、不易出错:
unsigned long color = 0xff0088; int r = (color >> 16) & 0xff; int g = (color >> 8) & 0xff; int b = color & 0xff;
注意:高位在前(RGB 顺序),所以红色在最高 8 位。如果误写成 (color & 0xff0000) >> 16 也行,但括号易漏,直接右移更少出错。
- 不要用
color / 0x10000算 R —— 除法语义弱,且对无符号数虽安全,但可读性差 - 确保每个分量是
int类型(0–255),别用char存,避免符号问题影响后续计算 - 如果需要 alpha,默认设为 255(不透明),除非输入含 8 位格式(如
"#ff0088cc")
封装成函数时,返回结构体比 tuple 更清晰
返回 std::tuple<int></int> 或三个输出参数,调用方容易搞混顺序;定义一个轻量结构体,字段名即语义:
struct RGB {
int r, g, b;
};
这样调用侧写 auto rgb = hex_to_rgb("#ff0088"); rgb.r 就一目了然。C++17 后也可用结构化绑定:auto [r,g,b] = hex_to_rgb(...);,但前提是返回类型支持。
- 函数签名建议为
std::optional<rgb></rgb>(C++17),失败时返回std::nullopt,比传引用+bool 返回值更现代、不易忽略错误 - 若项目未启用 C++17,退而用指针或 bool 返回值 + 引用输出参数,但必须文档注明“失败时输出参数值未定义”
- 别为了省几行代码把解析逻辑塞进一行 lambda —— 颜色解析是边界操作,可读性和错误处理比简洁重要
"f08" 或空字符串就崩。C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










