首页 > 解决方案 > 抛出实例'std :: out_of_range'后调用c ++终止what():basic_string :: substr:__pos> this->size()

问题描述

问题:

给定一个包含 m 个空格、线索和每个线索最多 n 个单词的单词测验 (3<=m,n<=100)

输入的第一行包含 m,n。

接下来的 m 行包含单词 quiz 和您需要填写的线索。

您需要填写的空白标记为1,您不需要填写的空白标记为0。

输出是我们填写后的单词测验。

所以我尝试如下解决,但它一直被终止。我是初学者,这是我第一次发布问题,所以任何帮助都会对我有很大帮助!

输入:

3 8
011G1100
1A111000
00000C11
CAT
NIGHT
DOG

输出:

0NIGHT00
CANDY000
00000CAT

代码

#include <iostream>
#include <string>
#include <vector>

using namespace std;

int main(){

    short m,n;

    cin >> m >> n; //input

    vector <string> map(m); //map is the word quiz

    vector <string> clue(m); //clue

    for (int i=1; i<=m;i++){
        string dd;
        cin >> dd;
        map.push_back(dd); //lines of the word quiz
    }
    cout << endl;

    for (int i=1; i<=m;i++){
        string dd;
        cin >> dd;
        clue.push_back(dd); //lines of clues
    }

    for (int i=1; i<=m;i++){
        string str= map[i];
        int pos = str.find_first_not_of("0");      
        int pos2 = str.find_last_not_of("0");
        string str3 = str.substr (pos,pos2-pos+1);    //find the substring which don't have '0' 

        for (int j =1; j<=m;j++){
            string mclue = clue [j];    
            if (str3.length() == mclue.length()){    //check if the length of the clue is the same as the length of the line

                for(int k =0;k<= str3.length();k++){
                    if (str3.at(k)==mclue.at(k)){    //check if there is a similar letter between the clue and the line
                        string str4 = str.replace(pos,pos2-pos+1,mclue);
                        cout << str4; //output
                        break;
                    }
                }
            }
        }
    }

标签: c++stringvector

解决方案


for (int i=1; i<=m;i++){
    string str= map[i];
    ...
}

这个循环是错误的。map[i]当 时将超出向量的范围i == m,因此对返回的任何使用都string&将是未定义的行为(包括 的初始化str)。但是您没有收到运行时错误,因为vector::operator[]不执行边界检查。如果你map.at(i)改用,你会得到一个运行时错误。

请改用此循环:

for (size_t i = 0; i < m; ++i)

此外,当未找到匹配项时,这些std::string::find...()方法会返回std::string::npos(aka )。std::string::size_type(-1)但是您没有检查这种情况。 size_type是一个无符号类型,因此分配npos给一个有符号int将产生一个值-1,当分配回一个时size_type(例如在pos参数中std::string::substr())将产生一个非常大的无符号数。 当其参数超出字符串的范围时str.substr()抛出。std::out_of_rangepos

您需要验证的结果std::string::find...(),例如:

size_t pos = str.find_first_not_of("0");
if (pos == std::string::npos) {
    // not found, do something...
}
size_t pos2 = str.find_last_not_of("0");
if (pos2 == std::string::npos) {
    // not found, do something...
}

推荐阅读