【问题标题】:why cout is not printing this string?为什么 cout 不打印这个字符串?
【发布时间】:2020-11-08 05:02:45
【问题描述】:

所以,我是 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;
}

任何帮助将不胜感激!

【问题讨论】:

  • ios::sync_with_stdio(false); cin.tie(0); - 为什么这么多废话?
  • @JesperJuhl • (deadpan) 所以程序是高效的。否则会太慢。 (/deadpan)
  • 你没有#include &lt;string&gt;,但是你无缘无故地添加了各种sync_with_stdio的东西..
  • 您使用 c-strings 标记了问题,但您的代码中没有任何 c-strings。

标签: c++ c++17 stdstring


【解决方案1】:

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

您可以使用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, '\0'); // or... string s2; s2.resize(10);
for(int i=0; i<10; i++){
    s2[i] = s[i];
}

【讨论】:

    【解决方案2】:

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

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

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

       string s2(10, '\0');
       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);
      

    【讨论】:

    • 另一种可能的解决方案,对初学者来说可能更清楚string s2(s, 0, 10);
    • @S.M.伟大的。不知道。
    【解决方案3】:

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

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

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

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

    如果问题的代码被执行了几次,可以看到这个snipped的未定义行为。

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-08-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-16
      • 1970-01-01
      • 2012-09-13
      • 2013-07-11
      相关资源
      最近更新 更多