我尝试了以下程序:
#include <iostream>
#include <string>
int main ()
{
std::string str;
str[0] = 'o';
str[1] = 'k';
std::cout << str.length();
std::cout << "as a whole :";
std::cout << str << std::endl;
std::cout << "character by character :";
std::cout << str[0] << str[1] << std::endl;
return 0;
}
我不明白为什么我不能使用对象变量将字符串作为一个整体打印,为什么长度返回为0
,因为很明显,我已经使用下标运算符添加了字符,因为这会返回char引用,所以我知道这是合法的。
此外,我没有得到任何例外。就是这样。显然,std::string
类的幕后发生了很多事情,我知道我错过了一些东西。有人能帮我吗?
您有一个长度为0
的字符串,然后尝试使用下标运算符修改其内容。这是未定义的行为,所以在这一点上,没有特定的结果是可以保证的。如果您使用at()
,它会暴露错误并引发异常。
为什么长度返回为0
它最初是0
,您没有做任何添加操作(例如push_back
或+=
(。但话说回来,由于你之前所做的是未定义的行为,任何事情都可能在这里发生。
此外,我没有得到任何类型的异常。
您可以改为尝试std::string::at
,当您尝试时会抛出std::out_of_range
异常。
我不明白为什么我不能打印整个字符串[…]…
因为您正在经历未定义的行为。
这个
std::string str;
构造具有CCD_ 10内存分配的默认字符串。这意味着通过std::string::operator[]
进行修改将导致未定义行为超出范围。因此,任何事情都有可能发生。在您的情况下,长度返回0
。
[…]很明显,我已经使用下标运算符添加了字符因为这会返回字符引用,所以我知道这是合法的。
否,由于上述原因,您没有。作为参考,std::string::operator[]
返回对指定位置的字符的引用。不执行边界检查。如果pos>size((,则行为未定义
作为可能的修复,您可能希望在访问元素之前std::string::resize
。
#include <string>
std::string str;
str.resize(2);
str[0] = 'o';
str[1] = 'k';
// ... now it has defined behaviour
或者CCD_ 15的每一个charector到串中。
#include <string>
std::string str;
str.push_back('o');
str.push_back('k');
// ... now it has defined behaviour
您没有向空字符串str
添加任何内容。相反,您正在尝试编辑空字符串中不存在的元素。std::string
的下标运算符不会自动添加元素。(与std::map
不同(此外,不能保证下标运算符会抛出一些异常。如果您想要安全的下标操作,您可以使用std::string::at
函数。
可以使用+=
运算符将某些内容附加到字符串中。
str += 'o';
str += 'k';