繁体   English   中英

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

[英]c++ string.length() out of range as string.at() parameters

因此,我一直在研究一个可以反转字符的程序。 我已经通过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;
}

错误在这里:

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开始,另一个从字符串末尾开始。 每一步都增加temp1temp2 您必须区分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。 有关无符号整数下溢的C行为问题,请参见问题更多。

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

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

使用“ bar”之类的输入,而不是在那里使用的那么大的字符串,您可以轻松地看到,当它变成“ rab”时, temp1等于2,而temp2等于0。

如果允许再次执行循环的主体,则将允许temp2下溢,并在尝试使用temp2调用未定义行为(UB)

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


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

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


PS:既然我们讨论了下溢,现在应该自然有人认为必须确保temp不为空。 如果是,则此temp2 = temp.length() - 1; 会导致temp2下溢!

因此,修改您的函数以在其第一行中执行if(temp.length() == 0) return "";

这一个就足够了(一点点吻):

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM