2016-08-02 3 views
-5

Когда я запускаю эту программу, цикл делает то, что он должен делать, но также по какой-то причине завершает программу, в необычный способ. Что здесь не так?Завершить вызов после экземпляра 'std :: out_of_range' what(): basic_string :: compare C++

Это файл данных открывает:

Peter Y Y N Y Y N 

Sarah Y Y Y Y Y Y 

Bongi Y Y Y N N N 

Diane Y N Y N Y Y 

Betty N Y Y Y Y N 

Код:

#include<iostream> 
#include<fstream> 
#include<cstdlib> 
#include<cstring> 

using namespace std; 

int main() 
{ 
    ifstream in_stream; 
    in_stream.open("answers.dat"); 
    if (in_stream.fail()) 
    { 
     cout<<"Input file opening failed"<<endl; 
     exit(1); 
    } 
    string line; 
    int q1,q2,q3,q4,q5,q6; 
    int prize_money; 

    int loop=0; 
    string array[20]; 
    while (!in_stream.eof()) 
    { 
     getline(in_stream,line); 
     array[loop]=line; 

     if ((line.compare(10,1,"Y")==0)&&(line.compare(14,1,"Y")==0)) 
     { 
      if (line.compare(6,1,"Y")==0) 
      { 
       q1=1000; 
      } 
      else 
      { 
       q1=0; 
      } 
      if (line.compare(8,1,"Y")==0) 
      { 
       q2=2000; 
      } 
      else 
      { 
       q2=0; 
      } 
      if (line.compare(10,1,"Y")==0) 
      { 
       q3=3000; 
      } 
      else 
      { 
       q3=0; 
      } 
      if (line.compare(12,1,"Y")==0) 
      { 
       q4=4000; 
      } 
      else 
      { 
       q4=0; 
      } 
      if (line.compare(14,1,"Y")==0) 
      { 
       q5=5000; 
      } 
      else 
      { 
       q5=0; 
      } 
      if (line.compare(16,1,"Y")==0) 
      { 
       q6=6000; 
      } 
      else 
      { 
       q6=0; 
      } 

      prize_money=q1+q2+q3+q4+q5+q6; 
      cout<<line.substr(0,5)<<" R"<<prize_money<<endl; 
     } 

     loop++; 
    } 

    cout<<"Test to see if program goes beyond the loop"<<endl; 

    in_stream.close(); 
    return 0; 
} 

Когда я запускаю программу, она отображает победителей и правильно суммы, но появляется окна диалоговое окно, которое собирает больше информации и хочет закрыть программу. Как только я закрою это сообщение, на экране появится сообщение:

te rminate вызывается после экземпляра 'std :: out_of_range' what(): basic_string :: compare. Эта программа попросила Runtime прекратить необычным способом. Обратитесь в службу поддержки за дополнительной информацией.

+3

Форматирование пожалуйста. И используйте отладчик ... – LogicStuff

+1

Это та же проблема: http://stackoverflow.com/questions/5431941/why-is-while-feof-file-always-wrong Вы не можете использовать 'eof' для проверки конца file ** before ** call 'getline' – Ari0nhh

+0

Могу ли я также добавить, что' array [] 'и сохранение строк, прочитанных для всего времени выполнения, совершенно бессмысленно в этом коде. Его нужно устранить, а не только потому, что это бессмысленно. Он также лишен всех и всех пограничных проверок и может легко преуспеть в состоянии переполнения, что приводит к * неопределенному поведению *. – WhozCraig

ответ

1

Если последняя строка, которую она читает, пуста, и вы пытаетесь прочитать символ 10 этой строки, она не удастся. Вы должны проверить длину строки перед тестированием для символов в ней.

Кроме того, кто-нибудь проинструктировал вас, что с помощью std::istream::eof в качестве управления контуром, как это сделать, вы можете сказать им, что они ошибаются во всех, кроме самых тонких обстоятельств, ни одна из которых не отображается в вашем опубликованном коде. See this question and answers для получения дополнительной информации о том, почему.

Наконец-то вам повезло, что никто из нас не назвал «Джон», «Уильям», «Джейн» или «Аннабель» записал данные. Ваш алгоритм ужасно хрупкий, полагаясь на длину имен, чтобы оставаться строгой константой не более, и не менее, чем ровно пять символов.

Я думаю, что-то такое, как это было бы более в соответствии с тем, что должно быть сделано:

#include <iostream> 
#include <fstream> 
#include <sstream> 
#include <string> 
#include <cstdlib> 

int main() 
{ 
    std::ifstream in_stream("answers.dat"); 
    if (in_stream.fail()) 
    { 
     std::cerr << "Input file opening failed\n"; 
     exit(EXIT_FAILURE); 
    } 

    std::string line; 
    while (std::getline(in_stream, line)) 
    { 
     std::istringstream iss(line); 
     std::string name; 
     if (iss >> name) 
     { 
      static const int prize[] = { 1000, 2000, 3000, 4000, 5000, 6000 }; 
      static const size_t n_prizes = sizeof prize/sizeof *prize; 

      int prize_money = 0; 
      std::string yesno; 
      for (size_t i=0; i<n_prizes && iss >> yesno; ++i) 
      { 
       if (yesno == "Y") 
        prize_money += prize[i]; 
      } 

      std::cout << name << " R" << prize_money << '\n'; 
     } 
    } 

    return EXIT_SUCCESS; 
} 

Что-то вроде этого, во всяком случае.

+0

Большое спасибо. Это прекрасно работает, и вы объяснили это очень хорошо. Он предназначен для первого курса университетского модуля. Я никогда не видел его раньше, и не вижу его в моем предписанном руководстве. Я узнал кое-что здесь, спасибо снова. – Jakkie

+0

Большое спасибо. Ваша программа не сбой, но она не проверяет, правильно ли отвечают ответы 3 и 5. Я должен был более подробно упомянуть об этом в своем вопросе, что это необходимо. Это для присвоения для первого курса университетского модуля. В любом случае, я просто изменил условие цикла, чтобы не включить eof, а скорее ваш цикл getline. И это работает! Кстати, я никогда раньше не видел его, и не вижу его в моем предписанном руководстве. Я узнал кое-что здесь, спасибо снова. Мой код ниже. – Jakkie

0
#include<iostream 
#include<fstream> 
#include<cstdlib> 
#include<cstring> 
#include<iomanip> 
using namespace std; 

int main() 
    {ifstream in_stream; 
in_stream.open("answers.dat"); 
if (in_stream.fail()) 
{cout<<"Input file opening failed"<<endl; 
exit(1);} 
    string line; 
int q1,q2,q3,q4,q5,q6; 
    int prize_money; 


int loop=0; 
string array[18]; 
while (getline(in_stream,line)) 

{array[loop]=line; 

    if ((line.compare(10,1,"Y")==0)&&(line.compare(14,1,"Y")==0)) 
{ if (line.compare(6,1,"Y")==0) 
{q1=1000;} 
else {q1=0;} 
if (line.compare(8,1,"Y")==0) 
{q2=2000;} 
else {q2=0;} 
if (line.compare(10,1,"Y")==0) 
{q3=3000;} 
else {q3=0;} 
if (line.compare(12,1,"Y")==0) 
{q4=4000;} 
else {q4=0;} 
if (line.compare(14,1,"Y")==0) 
{q5=5000;} 
else {q5=0;} 
if (line.compare(16,1,"Y")==0) 
{q6=6000;} 
else {q6=0;} 

prize_money=q1+q2+q3+q4+q5+q6; 
    cout<<line.substr(0,5)<<" R"<<prize_money<<endl; 
} 

loop++;} 

cout<<"Test to see if program goes beyond the loop"<<endl;//indeed it does 

in_stream.close(); 
return 0; 
}