簡體   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