【问题标题】:results in stopped working when running reverse string program运行反向字符串程序时导致停止工作
【发布时间】:2025-12-16 12:05:02
【问题描述】:

我在 C++ 中编写了反转字符串的函数,但它导致“停止工作”。

#include<iostream>
#include<string.h>
using namespace std;

string reverse(string s1)
{
    string s2;
    for(int i=0;i<s1.length();i++)s2[i]=s1[s1.length()-i-1];
    return s2;
}

int main()
{
    string s1,s2;

    cin>>s1;
    s2=reverse(s1);
    cout<<s2;

}

可能是什么问题?

【问题讨论】:

  • 你没有从int main()返回任何东西。 main() 是一个和其他函数一样的函数,它有一个返回值,所以 return 0 或任何合适的值。这可能会解决您的问题。
  • reverse() 函数中结果字符串的长度是多少?
  • @Jonathon return 0 in main 是隐含的,您不必提供它。
  • @JonathonOgden main 是一个例外,您不必返回某些东西,在这种情况下它将return 0
  • 顺便说一句,标头是&lt;string&gt;&lt;string.h&gt; 是一个 C 标头,如果您需要它,您应该将它包含为 &lt;cstring&gt;(您不需要此代码)。

标签: c++ string algorithm reverse


【解决方案1】:

问题是您在其边界之外访问字符串 s2。您只能访问已存在的带有 [] 的字符;尝试在字符串之外写入会导致未定义的行为。

一种可能的解决方案是预先分配 s2:

string s2 = s1;

另一种选择是倒计时 s1,然后简单地将新字符添加到 s2 的末尾。

【讨论】:

    【解决方案2】:

    函数声明有一个缺点。首先实际上它不会反转字符串。它以相反的顺序复制一个字符串。

    另外,将参数声明为常量引用更有效。

    例如

    std::string reverse_copy( const std::string &s );
    

    在函数中,您正在使用应用于空字符串的下标运算符

    string s2; // the string is empty
    for(int i=0;i<s1.length();i++)s2[i]=s1[s1.length()-i-1];
                                  ^^^^^
    

    这会导致未定义的行为。

    除了int 类型的索引,最好使用std::string::size_type 类型的索引。

    该函数可以在没有任何显式循环的情况下编写。例如

    std::string reverse_copy( const std::string &s );
    {
        return std::string( s.rbegin(), s.rend() );
    }
    

    如果你想使用循环,那么函数可以看起来像

    std::string reverse_copy( const std::string &s );
    {
        std::string t;
        t.reserve( s.size() );
    
        for ( auto i = s.size(); i != 0; --i ) t.push_back( s[i-1] );
    
        return t;
    }
    

    代替语句

    t.push_back( s[i-1] );
    

    你也可以写

    t += s[i-1];
    

    例如

    std::string reverse_copy( const std::string &s );
    {
        std::string t;
        t.reserve( s.size() );
    
        for ( auto i = s.size(); i != 0; --i ) t += s[i-1];
    
        return t;
    }
    

    【讨论】:

    • return std::string( s.rbegin(), s.rend() ); 特别优雅。加一。
    【解决方案3】:

    当字符串还没有形成时,你不能索引到它。

    更正您的代码如下并附加到s2,而不是对其进行索引

    string reverse(string s1)
    {
        string s2;
        for (int i = 0; i<s1.length(); i++)
            s2 += s1[s1.length() - i - 1];
    
        return s2;
    }
    

    【讨论】:

    • yapp 现在我明白其中的原因了!!
    【解决方案4】:

    如果你没有使用标准算法,问题几乎总是你没有使用标准算法。

    #include <iostream>
    #include <string>
    #include <algorithm>
    #include <iterator>
    
    std::string reverse(const std::string& s)
    {
        std::string result;
        result.reserve(s.size());
        std::copy(s.rbegin(), s.rend(), std::back_inserter(result));
        return result;
    }
    int main()
    {
        auto s = std::string("Hello, World");
        auto s2 = reverse(s);
    
        std::cout << s << std::endl;
        std::cout << s2 << std::endl;
    
        return 0;
    }
    

    预期结果:

    Hello, World
    dlroW ,olleH
    

    【讨论】:

      【解决方案5】:

      s2 没有明确定义的长度:您假设它的长度至少与s1 相同。具体来说,s2[i] 的行为是未定义

      考虑基于 C++ 标准库的解决方案

      std::string s2(s1);
      std::reverse(s2.begin(), s2.end());
      

      从概念上讲,我将字符串视为chars 的容器。使用标准函数意味着查看您的代码的人知道确切您是什么做。

      【讨论】: