首选std::string::empty()判断是否为空,时间复杂度o(1)、语义清晰安全;c风格字符串需先判空指针再判首字符是否为'\0';含空白字符需先trim再判空。

用 empty() 是最安全直接的方式
判断 C++ 字符串是否为空,首选 std::string::empty() 成员函数。它不检查内容、不计算长度,只读取内部长度字段,时间复杂度 O(1),且语义清晰、无歧义。
常见错误是用 length() == 0 或 size() == 0 —— 虽然结果等价,但可读性稍弱;更危险的是用 str == "",这会触发临时对象构造和 operator== 比较,多一次内存分配和逐字符比对,纯属浪费。
-
empty()对空字符串、刚默认构造的std::string、或调用过clear()的对象都返回true - 它不依赖 null 终止符,也不关心底层是否用了 SSO(短字符串优化),完全封装实现细节
- 对
std::string_view同样适用:sv.empty(),且同样 O(1)
别拿 c_str() 和 [0] 去判空
有人习惯写 str.c_str()[0] == '\0' 或 str[0] == '\0',这是错的,而且可能崩溃。
std::string 不保证以 '\0' 结尾(虽然通常有,但标准只要求 c_str() 返回时添加),而 str[0] 在空串时是越界访问 —— operator[] 不做空检查,行为未定义。用 at(0) 倒是会抛异常,但没必要绕这么大弯子。
- 空
std::string的size()是 0,所以str[0]等价于str[0]访问不存在的元素 -
c_str()返回的指针在空串时确实指向一个 '\0',但依赖这个属于碰运气,不是契约 - 如果字符串含嵌入 '\0'(比如从二进制数据构造),
c_str()[0] == '\0'会误判为“空”,哪怕实际长度 > 0
注意 std::string 和 C 风格字符串的混淆
如果你拿到的是 const char*(比如函数参数、宏定义、C API 返回值),那根本不能调用 empty() —— 它不是 std::string 对象。这时候得先确认指针非空,再看首字节:
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
if (cstr == nullptr || cstr[0] == '\0') {
// 空或无效指针
}
但要注意:这个判断只表示“内容为空”,不代表该指针指向合法的 C 字符串(比如没保证以 '\0' 结尾)。如果来源不可信,用 strlen() 前必须确保它是 null-terminated,否则会越界读。
-
nullptr和空字符串("")是两回事,都要单独处理 - 不要把
const char*强转成std::string再调empty(),除非你明确需要拷贝——徒增开销 - 若频繁混用,考虑统一用
std::string_view接口,它能隐式构造自const char*和std::string,且empty()行为一致
初始化和赋值后记得检查实际内容
有些看似“空”的字符串其实藏着空白字符,比如 " " 或 "\n\t"。这时 empty() 返回 false,但业务上可能算“逻辑空”。没有通用解法,得按需 trim 后再判:
auto trimmed = str;
trimmed.erase(trimmed.begin(), std::find_if_not(trimmed.begin(), trimmed.end(), ::isspace));
trimmed.erase(std::find_if_not(trimmed.rbegin(), trimmed.rend(), ::isspace).base(), trimmed.end());
if (trimmed.empty()) { ... }
不过注意:这依赖 locale 和 ::isspace 行为,Windows 下可能和预期不符;更健壮的做法是手写基于 std::is_space 的 lambda,或用第三方库如 abseil 的 absl::StripAsciiWhitespace。
真正容易被忽略的是:字符串对象本身不空,但所含数据来自不可靠输入(如文件读取失败、网络截断、编码错误),此时 empty() 正确返回 false,但后续操作仍可能出错——空检查只是第一道关,不是万能保险。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










