c ++ string.length()作为string.at()参数超出范围

时间:2018-11-21 12:30:44

标签: c++ string

所以我一直在研究一个程序来反转其字符。我已经通过string.length()和string.at()做到了。但是,即使它没有超出范围,也会发生错误“超出范围”(我已经通过打印variabele的pos进行检查),我怀疑这是由数据类型不匹配引起的。如果我错了纠正我。这是我的代码。

 #include "pch.h"
#include <iostream>
#include <conio.h>
#include <string>

using namespace std;

string compose(string temp) {
    size_t temp1 = 0, temp2 = temp.length() - 1;
    string temporary, temporary1;
    cout << temp2;
    while (temp2 < temp.length() / 2 + 1 || temp2 > temp.length() / 2 - 1) {
        temporary1 = temp.at(temp1);
        temporary = temp.at(temp2);

        temp.replace(temp1, 1, temporary);
        temp.replace(temp2, 1, temporary1);
        temp1++;
        temp2--;
    }
    return temp;
}

int main()
{

    cout << compose("RPL X-1okewphevoiwrwrejfnjjjjjjjjjjjjjjjjjnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn");
    _getch();
    return 0;
}

3 个答案:

答案 0 :(得分:2)

错误在这里:

while (temp2 < temp.length() / 2 + 1 || temp2 > temp.length() / 2 - 1) {
                                 ^-- should be -1

但是实际上检查本身是错误的。从理论上讲,正确的是:

while (temp1 < temp.length() / 2 - 1 || temp2 > temp.length() / 2 - 1) {
           ^-- change here

但是,甚至太多了。只是检查

while (temp1 < temp.length() / 2 - 1)

应该足够了。原因是您有temp1temp2,其中一个从0开始,另一个从字符串末尾开始。每增加一个步骤,temp1就会减少temp2。您必须区分两种情况:

  • 字符串长度是均匀的
  • 字符串长度很奇怪

但是对于这两种情况,仅检查变量之一是要通过字符串(甚至是长度字符串)的一半,还是要碰到中间的字符(奇数长度的字符串),而这是没有意义的,就足够了。< / p>

正如“轨道中的竞速比赛”在评论中提到的那样,您必须确保传递的字符串不为空。但是在那种情况下,您可以返回。

答案 1 :(得分:2)

更改此:

while (temp2 < temp.length() / 2 + 1 || temp2 > temp.length() / 2 - 1)

收件人:

while (temp2 < temp.length() / 2 - 1 || temp2 > temp.length() / 2 - 1)

说明:

  

我已经通过在variabele上打印pos来检查了它

您的支票不足。我做了:

cout << temp1 << " " << temp2 << endl;

在while循环主体的第一行,很明显temp2正在下溢,这说明了超出范围的错误。

您要做的是强制size_t(将其想象为无符号整数)变量小于0。在Question about C behaviour for unsigned integer underflow中了解更多信息。

为了解决此问题,您需要了解什么导致temp2下溢。在循环结束时,您执行temp2--;,将temp2减1。

您应该通过在while循环中设置停止条件来控制执行此操作的次数。 Thats方法使我们可以专注于while循环中的停止条件。

使用“ bar”之类的输入,而不是在那里使用的大字符串,您可以很容易地看到,当它变成“ rab”时,temp1等于2并且{{1 }}等于0。

如果您允许再次执行循环的主体,则当您尝试使用{时,将允许temp2下溢,调用未定义行为(UB) {1}}。

检查停止条件和计数器的值,可以看到您需要更改OR条件的第一个操作数,如上所述。


家庭作业:考虑如何简化停止条件。以一个小的字符串作为示例输入,并查看计数器temp2temp2自身如何更新。

提示:一个条件就足够了(您不需要两个条件与逻辑或配对)。


PS:既然我们讨论了下溢,现在自然应该有人认为必须确保temp1不为空。如果是的话,那么此temp2将导致temp下溢!

因此,将函数修改为在第一行temp2 = temp.length() - 1;中执行。

答案 2 :(得分:0)

这应该足够了(一点点吻):

#include <iostream>
#include <string>

using namespace std;

string compose(string temp) {
    size_t temp1 = 0, temp2 = temp.length() - 1;
    string temporary, temporary1;

    size_t size = temp.length() /2;
    size = size %2 == 0? size: size -1;
    while (temp1 <= size) {
        temporary1 = temp.at(temp1);
        temporary = temp.at(temp2);

        temp.replace(temp1, 1, temporary);
        temp.replace(temp2, 1, temporary1);
        temp1++;
        temp2--;
    }
    return temp;
}

int main()
{

    cout << compose("RPL X-1okewphevoiwrwrejfnjjjjjjjjjjjjjjjjj123456789");
    cout << compose("1234");    
    cout << compose("12345");    
    return 0;
}