【问题标题】:How to fix terminate called after throwing an instance of std::out_of_range如何在抛出 std::out_of_range 的实例后修复终止调用
【发布时间】:2017-03-27 00:36:28
【问题描述】:

这是消息:

terminate called after throwing an instance of 'std::out_of_range'
  what():  basic_string::erase: __pos (which is 18446744073709551615) > this->size() (which is 22)
Aborted (core dumped)

下面是我到目前为止的代码(它应该重新格式化加扰数据文件中的名称、日期和金额,使其看起来像:

Foster, Jerry Lee 1995   329,475

//This program reformats the retirement account data file oldretirement.txt and outputs the data into a new file newretirement.txt


#include<iostream>
#include<cstdlib>
#include<fstream>
#include<cctype>
#include<string>
#include<cstring>
#include<cstddef> 

using namespace std;

void getridof(string &line);
int splitamount(string &line);
int splityear(string &line);
string splitfullname(string &line);

int main(){

 ifstream fin;
 ofstream fout;
 string line;
 string finalname;
 size_t found;
 int finalamount;
 int finalyear;

 fin.open("oldretirement.txt");
 if(fin.fail())
  {cout<< "input file failed to open. \n";
   exit (1);}
 fout.open("newretirement.txt");
 if(fout.fail())
  {cout<<"output file failed to open.\n";
   exit (1);}

while(!fin.eof()){
 getline(fin,line);
// getridof(line); 
 finalamount = splitamount(line);
 finalyear = splityear(line);
 getridof(line);

// found = line.find(",");
// if(found!=string::npos)
 // {finalname = line;}
// else
 // {finalname = splitfullname(line);} 

fout << finalname << finalyear << finalamount << endl;
}
fin.close();
fout.close();
}


void getridof(string &line){
 int location = 0;
 location=line.find("Account$:");
cout << location << endl;
 if(location != 0){
 // location=line.find("Account$:");
  line.erase(location,9);}
 cout<< "get rid of a " << line << endl;
location = line.find("born:");
 if(location != -1){
 // location=line.find("Account$:");
  line.erase(location,5);}
 cout<< "get rid of b " << line << endl;

return;
}

int splitamount(string &line){

 int a;
 size_t found = -1;
 int num_len;
 line.erase(line.find_last_of(","),1);
 cout << "amount a " <<  line << endl;
 found=line.find_last_of((" "));
 num_len=line.length()-found;
 char amount[num_len];
 for(int i=0;i<num_len;i++){
 amount[i] = line[found + 1 + i];
 }
 line=line.substr(0,found);
cout << "amount b " << line<< endl;
 a=atoi(amount);
cout << "amount c "  << a << endl;
 return a;
}

int splityear(string &line){
 char year[4];
 int y;
 size_t found = -1;
cout << "split year a " << line << endl;
 found =  line.find_first_of("1",1);
 for(int i=0;i<4;i++){
year[i] = line[found+i];
 }
 line=line.erase(found,4);
 y=atoi(year);
cout << "split year b " << line << endl;

cout << "split year c " << y << endl;
 return y;
}

string splitfullname(string &line){
 string last;
 string rest = ", ";
 string fullname;
 size_t found = -1;
 found = line.find_last_of(" ");
 last = line.substr(found+1);
// line.erase(found,string::npos);
 rest.insert(3,line);
 fullname = last + rest;
 return fullname;
}

//temp=line.substr(line.first_of("1",0))
//get today's date and subtract integer version of birth dates in data from today's date. (finalyear atoi) (age = currentyear-intyear) do in main.

【问题讨论】:

  • 使用调试器确定哪一行抛出异常。您使用的索引不正确(您的数组有 22 个元素,并且您的索引是 &lt; 0&gt;= 22)。

标签: c++ string terminate


【解决方案1】:

改变:

if(location != 0){

if(location != string::npos){

如果std::string::find() 没有找到匹配项,则函数返回string::nposnpos 是一个静态成员常量值,对于 size_t 类型的元素具有最大可能值。

这就是您看到价值 18446744073709551615 的原因,原因是 std::out_of_range`。

【讨论】:

  • 好的,所以我进行了更改,代码编译了列表中多个名称,但错误注释还没有消失。我必须在其他地方进行此更改吗?
  • 是的。调用find() 的所有地方。其他选项是进行范围检查0 &lt;= index &lt; size()
  • 好吧,我很难理解。我所有的 find() 在 () 中都有一些东西,比如 find("born:"),见第 66 行。那么我要替换 () 里面的东西吗?这对我来说没有意义
  • 好的,范围检查会在主目录中进行吗?
  • 这就是现在发生的事情:在抛出 'std::out_of_range' 的实例后调用终止 what(): basic_string::erase: __pos (即 18446744073709551615) > this->size() (这是0)中止(核心转储)
猜你喜欢
  • 2021-01-02
  • 2017-03-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多