为什么 cout 不打印这个字符串?

why cout is not printing this string?

所以,我是 C++ 的新手,我不明白为什么会这样。我有一个包含所有字母的字符串,我将其中的 10 个字符复制到一个新字符串 s2 中,使用 for 循环逐个字符如下所示,当我执行它时,cout 函数正在打印一个空白行。

#include <iostream>

using namespace std;

int main(){
    string s = "abcdefghijklmnopqrstuvwxyz";
    string s2;
    for(int i=0; i<10; i++){
        s2[i] = s[i];
    }
    cout << s2 << endl;
    return 0;
}

但是当我逐个字符打印这个字符串时 s2 我得到了正确的输出

#include <iostream>

using namespace std;

int main(){
    string s = "abcdefghijklmnopqrstuvwxyz";
    string s2;
    for(int i=0; i<10; i++){
        s2[i] = s[i];
    }
    
    for(int i=0; i<10; i++){
        cout << s2[i];
    }
    return 0;
}

如有任何帮助,我们将不胜感激!

你的两个代码都有 undefined behaviorstring s2; 只是将 s2 初始化为不包含任何元素的空 std::string。尝试访问元素作为 s2[i] 导致 UB,意味着一切皆有可能。 (即使它似乎在您的第二个代码片段中给出了正确的输出。)

您可以使用 push_back 将元素追加为

for(int i=0; i<10; i++){
    s2.push_back(s[i]);
}

for(int i=0; i<10; i++){
    s2 += s[i];
}

或者你可以预先让s2包含10个元素

string s2(10, '[=12=]'); // or... string s2; s2.resize(10);
for(int i=0; i<10; i++){
    s2[i] = s[i];
}

创建了一个空字符串 s2s2[i] = s[i]; 不会调整字符串的大小,但会导致未定义的行为。解决该问题的一种方法是附加每个字符。这将改变大小并且可能涉及多个内存分配。

另一种方法是创建一个具有正确大小的字符串或保留内存:

  1. 创建大小为 10 的“空”字符串:

     string s2(10, '[=10=]');
     for(int i=0; i<10; i++){
         s2[i] = s[i];
     }
    
  2. 预留内存

     string s2;
     s2.reserve(10);
     for(int i=0; i<10; i++){
         s2 += s[i];
     }
    
  3. 用子串初始化字符串

     string s2 = s.substr(0, 10);
    

     string s2(s.begin(), s.begin() + 10);
    

     string s2(s, 0, 10);
    

有人可能会感到困惑,因为

for(int i=0; i<10; i++){
    cout << s2[i];
}

提供正确的输出。 std::string 是具有函数和重载运算符的 class。 std::string[]-operator 显示与 char-array 类似的行为。 “数组元素”是用这段代码定义的:

for(int i=0; i<10; i++){
        s2[i] = s[i];
    }

如果题目的代码执行多次,可以看出这个snipped的undefined behavior

如果您尝试使用字符串迭代器,您会发现字符串 s2 仍然是一个空字符串。

string::iterator si;
    for (si=s2.begin(); si!=s2.end(); si++)
    {
        cout << *si ;
    }