【问题标题】:c++ terminate called after throwing an instance 'std::out_of_range' what(): basic_string::substr: __pos > this->size()抛出实例'std :: out_of_range'后调用c ++终止what():basic_string :: substr:__pos> this->size()
【发布时间】:2021-08-25 16:50:32
【问题描述】:

问题:

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

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

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

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

我们填完后输出的是单词quiz。

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

输入:

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

【问题讨论】:

  • 当您使用从零开始的数组时,此行已经存在问题for(int k =0;k&lt;= str3.length();k++){,您需要index &lt; size 而不是index &lt;= size
  • 建议:在调试器中运行程序,等待它崩溃,检查崩溃站点以获取更多详细信息,以便您可以缩小需要更仔细检查的感兴趣区域。逐步浏览感兴趣的区域,寻找程序做某事,通常采取错误的路径或存储错误的值,这是您意想不到的。意外通常是错误。
  • 请注意,std::string::size()/length() 是 C++11 及更高版本中std::string 的有效索引,它指的是字符串所需的空终止符。但是size()/length() 仅在operator[] 中作为索引有效,在at() 中无效,这太奇怪了。但是,引用的错误消息是 __pos &gt; this-&gt;size(),我认为在显示的代码中是不可能的,因为 k 不能大于 str3.length()mclue.length()
  • @RemyLebeau 确实如此。如果pos &gt; size(),则substr 调用会引发std::out_of_range
  • @RemyLebeau 我只是注意到它实际上在标题中:(但我第一次阅读时错过了它):-/

标签: c++ string vector


【解决方案1】:
for (int i=1; i<=m;i++){
    string str= map[i];
    ...
}

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

改用这个循环:

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

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

您需要验证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...
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-04
    • 1970-01-01
    • 1970-01-01
    • 2022-11-14
    相关资源
    最近更新 更多