运行反向字符串程序时导致停止工作

时间:2016-03-15 12:34:45

标签: c++ string algorithm reverse

  

我写了一个函数来反转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;

}
  

可能是什么问题?

5 个答案:

答案 0 :(得分:4)

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

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

string s2 = s1;

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

答案 1 :(得分:2)

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

将参数声明为常量引用也更有效。

例如

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

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

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;
}

答案 2 :(得分:1)

如果尚未形成字符串,则无法索引。

按如下方式更正您的代码并附加到s2而不是索引到其中

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

    return s2;
}

答案 3 :(得分:0)

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

#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

答案 4 :(得分:0)

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

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

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

在概念上,我将字符串视为char容器。使用标准函数意味着查看代码的人知道完全你正在做什么。