当我使用基于范围的 for 循环遍历临时std::string(右值?)时,似乎有一个额外的字符,即 null 终止符\0。
当字符串不是临时的(而是左值?)时,没有多余的字符。为什么?
std::map<char, int> m;
for (char c : "bar") m[c] = 0;
for (auto [c, f] : m) {
if (c == '\0') std::cout << "this is a null char, backward slash zero" << std::endl;
std::cout << c << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
输出:
this is a null char, backward slash zero
a
b
r
Run Code Online (Sandbox Code Playgroud)
\0(注意正在打印的空行)
相比:
std::map<char,int> m;
std::string s = "bar";
for (char c : s) m[c] = 0;
for (auto [c, f] : m) {
if (c == '\0') std::cout << "this is a null char, backward slash zero" << std::endl;
std::cout << c << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
输出:
a
b
r
Run Code Online (Sandbox Code Playgroud)
因为"bar"它不是一个std::string,而是一个包含 4 个元素的char数组 ( const char[4]) ,包括最后一个空字符。即c 风格的字符串文字:
空字符(
'\0'、L'\0'、char16_t()等)始终附加到字符串文字中:因此,字符串文字"Hello"是const char[6]保存字符'H'、'e'、'l'、'l'、'o'和 的'\0'。
对于临时std::strings ,它将按您的预期工作,即不包含空字符。
for (char c : std::string{"bar"}) m[c] = 0;
Run Code Online (Sandbox Code Playgroud)
或者
using namespace std::string_literals;
for (char c : "bar"s) m[c] = 0;
Run Code Online (Sandbox Code Playgroud)
顺便说一句,@HolyBlackCat 建议您还可以使用std::string_view(自 C++17 起),当从 c 样式字符串文字构造时,它不会包含以 null 结尾的字符。例如
for (char c : std::string_view{"bar"}) m[c] = 0;
Run Code Online (Sandbox Code Playgroud)
或者
using namespace std::literals;
for (char c : "bar"sv) m[c] = 0;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
506 次 |
| 最近记录: |