Цинковая петля никогда не заканчивается

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

100 20 50 100 40 -1
A34F 90 15 50 99 32 -1
N12O 80 15 34 90 22 -1

Первая часть — это общее количество баллов за класс, следующие строки — идентификационный номер ученика, за которым следуют их оценки, все заканчиваются -1.

Моя проблема: мой цикл while никогда не завершается, когда я запускаю команду ./a.out < hw07data, Может ли кто-нибудь просмотреть мой код и дать мне несколько советов? Я не хочу ответа, так как это домашняя работа, мне просто нужно руководство. Спасибо!!

#include <iostream>
#include <iomanip>
using namespace std;

const int SENTINEL = -1;           //signal to end part of file
const int LTAB = 8;                //left tab
const int RTAB = 13;               //right tab

int main()
{
cout << "Grant Mercer Assignment 7 Section 1002\n\n";
cout << setprecision(2) << fixed << showpoint;
cout << left << setw(LTAB) << "ID CODE" <<
right << setw(RTAB) << "POINTS" <<
setw(RTAB) << "PCT" << setw(RTAB) <<
"GRADE" << endl;
double Percentage,              //holds students percentage
AvgPercentage;
int Earnedpoints,               //earned points for specific student
Totalpoints,                //total points possible for all students
AvgPoints,                  //average points for all students
NumClass;                   //counts the number of students
Totalpoints = Earnedpoints =    //set all vals equal to zero
AvgPoints = AvgPercentage = Percentage =  NumClass = 0;
//first and last char for studentID
char Fchar,Lchar, Num1, Num2, Grade;

int TmpVal = 0;                 //temporary value
cin >> TmpVal;
while(TmpVal != -1)             //reading in TOTAL POINTS
{
Totalpoints += TmpVal;      //add scores onto each other
cin >> TmpVal;              //read in next value
}

while(cin)                       //WHILE LOOP ISSUE HERE!
{
//read in student initials
cin >> Fchar >> Num1 >> Num2 >> Lchar >> TmpVal;
while(TmpVal != -1)
{
Earnedpoints += TmpVal; //read in points earned
cin >> TmpVal;
}
//calculate percentage
Percentage = ((double)Earnedpoints / Totalpoints) * 100;
AvgPercentage += Percentage;
NumClass++;
if(Percentage >= 90)        //determine grade for student
Grade = 'A';
else if(Percentage >= 80 && Percentage < 90)
Grade = 'B';
else if(Percentage >= 70 && Percentage < 80)
Grade = 'C';
else if(Percentage >= 60 && Percentage < 70)
Grade = 'D';
else if(Percentage < 60)
Grade = 'F';
//display information on studentcout << left << Fchar << Num1 << Num2 << setw(LTAB) << Lchar << right << setw(RTAB-3) << Earnedpoints <<
setw(RTAB) << Percentage <<  setw(RTAB) << Grade << endl;
TmpVal = Earnedpoints = 0;
}
AvgPercentage /= NumClass;
cout << endl << left << setw(LTAB+20) << "Class size: " << right << setw(RTAB) << NumClass << endl;
cout << left << setw(LTAB+20) << "Total points possible: " << right << setw(RTAB) << Totalpoints << endl;
cout << left << setw(LTAB+20) << "Average point total: " << right << setw(RTAB) << AvgPoints << endl;
cout << left << setw(LTAB+20) << "Average percentage: " << right << setw(RTAB) << AvgPercentage << endl;
}

Выход продолжает запрашивать новый ввод.

1

Решение

Вы можете найти ответ там Как читать до EOF из Cin в C ++

Так что вы можете прочитать cin построчно используя getline и разобрать получающиеся строки, вот так:

#include <iostream>
#include <sstream>
#include <string>

int main() {
int a, b;

std::string line;
while (std::getline(std::cin, line)) {
std::stringstream stream(line);

stream >> a >> b;
std::cout << "a: " << a << " - b: " << b << std::endl;
}

return 0;
}

РЕДАКТИРОВАТЬ: Не забудьте проверить результаты синтаксического анализа и состояние потока на наличие ошибок!

1

Другие решения

Вам следует всегда проверьте, что ваш ввод был успешным:

if (std::cin >> TmpVal) {
// do simething with the read value
}
else {
// deal with failed input
}

В случае сбоя вы ночью хотите проверить eof() индуцируя, что отказ произошел из-за достижения конца ввода.

Чтобы справиться с ошибками, взгляните на std::istream::clear() а также std::istream::ignore(),

1