最基础的二进制字符串合法性判断是检查非空且每个字符均为'0'或'1';支持"0b"前缀需先剥离再校验;若要求无前导零,则仅允许"0"或以'1'开头的串;避免直接用std::stoul校验,因其行为不一致且易忽略空串或纯前缀输入。

检查字符串是否只含 '0' 和 '1' 字符
最基础的合法性判断,就是确保字符串中每个字符都是 '0' 或 '1',且不能为空。C++ 中可直接遍历或用 std::all_of 配合 lambda 实现:
bool is_valid_binary(const std::string& s) {
if (s.empty()) return false;
return std::all_of(s.begin(), s.end(), [](char c) { return c == '0' || c == '1'; });
}
注意:这个版本不跳过空格、不处理前缀(如 "0b101"),也不拒绝全零但长度合法的串(如 "000")——它只做字符集校验。
处理带 "0b" 前缀的常见格式
实际输入常来自用户或配置文件,可能带 "0b" 或 "0B" 前缀。需先剥离再验证内容:
- 用
s.starts_with("0b")(C++20)或手动比较前两位 - 若匹配,取子串
s.substr(2)后再校验;否则直接校验原串 - 必须保证剥离后子串非空,否则
"0b"本身会被误判为合法
示例逻辑:
立即学习“C++免费学习笔记(深入)”;
std::string content = s;
if (s.size() >= 2 && (s[0] == '0' && (s[1] == 'b' || s[1] == 'B'))) {
content = s.substr(2);
}
return !content.empty() && std::all_of(content.begin(), content.end(), [](char c) { return c == '0' || c == '1'; });
排除前导零导致的语义歧义(可选但实用)
严格来说,"00101" 是合法二进制字面量(C++ 标准允许),但某些场景(如协议字段、ID 编码)要求“无前导零”,即只接受 "0" 或以 '1' 开头的串:
- 允许单个
'0':s == "0" - 否则要求
s[0] == '1',再校验其余字符 - 这步应在字符集检查之后做,避免对空串或非法字符重复判断
比如:"000" → 不合法(非单个零且首字符不是 '1');"0" → 合法;"101" → 合法。
注意 std::stoi / std::stoul 的陷阱
别直接用 std::stoul(s, nullptr, 2) 来“验证+转换”——它在遇到非法字符时抛 std::invalid_argument,但对溢出抛 std::out_of_range,而且会静默跳过开头空白、接受前缀(取决于底层实现),行为不一致:
- 输入
"0b101":多数标准库会失败(基为 2 时不识别0b前缀) - 输入
"101 "(尾部空格):stoul可能成功解析并忽略空格,但你的业务可能要求严格无空格 - 输入超长串(如 1000 位):立即溢出,无法区分是格式错还是真超限
所以,校验和转换应分离:先用纯字符检查确认格式,再用 stoul 转换(并捕获溢出)。
真正容易被忽略的是空字符串和仅含前缀的输入(如 "0b"),它们在剥离逻辑里极易漏判,一不小心就让程序把空内容当作有效二进制数处理。


















