访问 std::string 中的空终止字符(字符串下标超出范围)
Posted
技术标签:
【中文标题】访问 std::string 中的空终止字符(字符串下标超出范围)【英文标题】:Accessing null-termination character in std::string (string subscript out of range) 【发布时间】:2013-08-18 13:32:35 【问题描述】:考虑以下非常简单的文本示例:
#include <stdio.h>
#include <string>
int main()
std::string x("ugabuga");
int i=0;
while (x[i])
++i;
printf("%d\n",i); //should print 7
return 0;
我希望程序遍历字符串的所有字符,然后到达终止循环的空终止字符并正确到达程序结束。 但是,当我尝试在 Visual Studio 2010 下以调试模式编译它时,我遇到了一个异常“字符串下标超出范围”。 在发布模式下编译时,此程序通过,但我的更大项目取决于此行为崩溃 - 可能是因为这个问题。
但是,当我在www.cplusplus.com 处检查std::string::operator[]
的规范时,会显式处理结束字符串:
如果 pos 等于字符串长度,则函数返回对空字符 ('\0') 的引用。
我想在这里问一下:
我对@987654324@ 规范的解释正确吗?还是我错过了什么? 如果问题出在实现的 VS 方面,我怎样才能轻松解决这个问题 - 希望每次使用operator[]
时都无需调用 length()
?例如使用c_str()[i]
会安全吗?
如果问题出在 VS 的实现方面 - 您是否知道它是否已在 VS 2012 中修复,或者将来可能会修复?
【问题讨论】:
【参考方案1】:这是 C++03 和 C++11 之间发生变化的事情之一。
这似乎是 C++03 中未定义的行为:
21.3.4 basic_string 元素访问[lib.string.access]
const_reference operator[](size_type pos) const;
reference operator[](size_type pos);
1 返回:如果
pos < size()
,则返回data()[pos]
。否则,如果pos == size()
,则为const version returns charT()
。否则,行为未定义。
在 C++11 中是可以的。
21.4.5 basic_string 元素访问[string.access]
const_reference operator[](size_type pos) const;
reference operator[](size_type pos);
1 要求:pos
2 返回:
*(begin() + pos)
如果pos < size()
,否则对类型为T
且值为charT();
的对象的引用不应修改引用的值。
【讨论】:
因此 OP 的解决方案是使用常量引用进行迭代:const std::string &cx = x; while (cx[i]) ...
。
@rodrigo 这将使它定义为行为。我不知道 OP 试图解决什么问题,但我怀疑有问题的 while
循环只是理解某些东西的一种手段。否则只会使用x.size()
。
感谢您的澄清。你知道 VS 在实现这些方面有多远吗?回答您的问题:我正在循环中实现一个简单的解析器。识别字母、数字、空格和字符串结尾。
@CygnusX1 抱歉,我不确定您需要哪个版本的 VS 才能获取 C++11 字符串。但是你可以遍历索引[0, x.size())
。
VS C++ 2010 及更高版本似乎有一个 std::string 根据 C++11 标准提供对终止空字符的访问。以上是关于访问 std::string 中的空终止字符(字符串下标超出范围)的主要内容,如果未能解决你的问题,请参考以下文章
使用类似 strndup 的语义从 char[] 创建 std::string
将 std::string_view 与 api 一起使用,期望以 null 终止的字符串