【问题标题】:String doesn't change字符串不变
【发布时间】:2018-12-08 13:03:55
【问题描述】:
string a;
string seq="AACCGGTT";

for (int i=0;i<seq.length();i++)
{
    if (seq[i]=='T')
    {
        a[i]='U';
        cout<<"i have turned: "<<seq[i]<<" into : "<<a[i]<<endl;
    }
    else
    {
        a[i]=seq[i];
        cout<<"i have turned: "<<seq[i]<<" into : "<<a[i]<<endl;
    }
}

cout<<"here: "<<a<<endl;

**

  • 当我运行它打印的大代码的这一部分时

我已经把:A 变成了:A

我已经把:A 变成了:A

我已经把:C 变成了:C

我已经把:G变成了:G

我已经把:G变成了:G

我已经把:T 变成了:U

我已经把:T 变成了:U

这里:

它不返回 a 的值

**

【问题讨论】:

  • a 为空。您不能只在其范围之外对其进行索引。
  • 不使用[ ],而是替换为a.at(i)='U';a.at(i)=seq[i];。然后你会看到having an exception thrown所犯的错误。

标签: c++ string c++11


【解决方案1】:

索引运算符[] 不会向a 附加任何内容,它只能让您访问a 中的现有 字符。由于a 中没有字符,所以你们每个人在a 上使用[] 都是未定义行为

要实际向a 附加内容,您可以使用a.append('U');a += 'U';

另一种方法是将a 初始化为seq 的副本,而不是空字符串。然后,您可以安全地在其上使用索引运算符,就像您现在正在尝试的那样。

您可能还需要考虑replace 函数,如here 所述。

【讨论】:

    【解决方案2】:

    在您的代码中,a 由以下默认构造函数创建。 例如,n3337(draft) 21.4.2 中的表 63 说

    explicit basic_string(const Allocator& a = Allocator());
    
    data(): a non-null pointer that is copyable and can have 0 added to it
    size(): 0
    capacity(): an unspecified value
    

    因此,您的代码中的a[i] 可能会显示一些未定义的行为。

    我认为替换特定字符最简单的方法是使用std::replace,如下所示。

    DEMO

    #include <iostream>
    #include <string>
    #include <algorithm>
    
    int main()
    {    
        std::string seq="AACCGGTT";
        std::replace(seq.begin(), seq.end(), 'T', 'U');
        
        std::cout << seq << std::endl; // "AACCGGUU"
        
        return 0;
    }
    

    【讨论】:

      【解决方案3】:

      a+=seq[i] 改为 a[i]=seq[i](当然 a+='U' 为) 问题是 a[i] 不能成为原因 a 为空的一部分 当您在循环中设置 a[i] 时,a[i] 代表编译器的不同变量。

      【讨论】:

      • 更一般地说,如果i 大于或等于a.length(),则a[i] 不是a 的一部分。你是对的,当a 为空时,没有索引是有效的; a.length() 为 0,因此没有大于或等于 a.length() 的索引值。
      【解决方案4】:

      因为您没有设置字符串a 的大小,所以它只保留了与您的实现的小字符串优化提供的一样多的空间。 (但请注意,即便如此,在初始化字符串之前对其进行索引也是未定义的行为。)

      您可以通过设置a 的大小来解决此问题,如下所示:

      string seq="AACCGGTT";
      string a;
      a.resize(seq.size();
      

      【讨论】:

      • 好吧,显然他的程序没有崩溃。否则,我相信他会注意到的。崩溃只是在未定义行为的情况下可能发生的无数行为之一。
      • 啊,你是……我看错了,以为最后一个 cout 根本没有发生……实际上,它只是将变量打印为空,因为它的大小为零。
      猜你喜欢
      • 1970-01-01
      • 2015-04-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-02
      • 1970-01-01
      • 2023-03-25
      • 1970-01-01
      相关资源
      最近更新 更多