Я пишу программу, которая принимает входные данные и форматирует их в балл как "Оценка имени". Вот что нужно сделать "Здесь формат Moonglow.
Текстовый файл состоит из слов. Если слово - это число, то это вопрос студента по вопросу, поэтому вы добавляете его на счет экзамена студента.
Если слово не является числом, но является словом "NAME", то следующим словом является имя студента (Moonglow использует только имена - фамилии являются корпоративными и безличными).
Если слово "AVERAGE", вы начинаете считывать цифры, пока не прочитаете слово, которое не является числом (или является концом файла). Вы усредняете все эти цифры и добавляете их в партитуру. Поскольку Moonglow немного рассеян, иногда число не следует "СРЕДНЕЕ". В этом случае вы игнорируете "СРЕДНЕЕ". "
Моя проблема заключается в том, что я каким-то образом вступил в бесконечный цикл и потратил часы, пытаясь это исправить. Это ОЧЕНЬ простая программа, и я не могу заставить ее работать!
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <stdlib.h>
using namespace std;
int main()
{
string s, name = "test";
string buffer;
double qScore, eScore, totalExam = 0, grade = 0, numExam = 0, finalGrade, avg = 0;
while (!cin.eof())
{
if (cin >> qScore)
{
if (cin.fail())
{
cin.clear();
}
else
{
grade += qScore;
}
}
else if (cin >> s)
{
if (s == "NAME")
{
cin >> s;
s = name;
}
else if (s == "AVERAGE")
{
while (cin >> eScore)
{
numExam++;
totalExam += eScore;
}
cin.clear();
}
}
}
if (numExam == 0)
{
avg = 0;
}
else
{
avg = (totalExam / numExam);
}
finalGrade = avg + grade;
cout << name << " " << finalGrade << endl;
return 0;
}
// end of main
Я не буду писать для вас код (так как это явно проблема домашних заданий), но я буду предлагать некоторые предложения относительно того, как я буду делать это совершенно по-другому. Надеюсь, этот псевдокод поможет.
EDIT: Я пропустил логику для AVERAGE и как должен работать счет, я делаю некоторые исправления. (Обратите внимание, что с этими изменениями может быть лучше добавить новые состояния. Я бы рассмотрел Normal, Name, BeginAverage, Average, EndAverage. Но это зависит от вас.)
1) Определите эти состояния (возможно, используйте перечисление):
2) Вы хотите прочитать один "токен" и переход со следующими правилами. Обратите внимание, что токеном в этом случае будет строка, разделенная пробелами (например, "NAME", "AVERAGE", "Bob", "11", "23").
3) Для обработки ввода сначала прочитайте все в строковой переменной. Затем вы можете использовать stringstream
для преобразования в double при необходимости. Просто прочитайте все строки (жетоны), как я описал, и обработайте их, как указано выше, до тех пор, пока вы не достигнете EOL.
"Код":
while (cin >> s)
{
if (state == state_normal)
{
if (s == "NAME") { state = state_name; }
else if (s == "AVERAGE")
{
state = state_average;
// You are starting a new average, initialize these variables to 0
scoresToAverage = 0;
numberOfScores = 0;
}
else if (isNumber(s))
{
number = convertToNumber(s);
score += number;
}
}
if (state == state_name)
{
name = s;
state = state_normal;
}
if (state == state_average)
{
bool calculateAverage = false;
if (s == "NAME")
{
state = state_name;
calculateAverage = true;
}
else if (s == "AVERAGE")
{
state = state_average;
calculateAverage = true;
}
else if (isNumber(s))
{
number = convertToNumber(s);
scoresToAverage += number;
numberOfScores++;
}
else
{
state = state_normal;
calculateAverage = true;
}
// If you are DONE averaging, calculate the average and add it to the total
if (calculateAverage)
{
if (numberOfScores > 0)
{
score += (scoresToAverage / numberOfScores);
}
scoresToAverage = 0;
numberOfScores = 0;
}
}
}
// done reading input, just print!
isNumber
берет строку и может просто проверить, что первый символ - это число ('0', '1',...). Это может быть более привлекательным и смотреть на каждый символ для чисел/десятичных знаков.
convertToNumber
берет строку и преобразует в double. Могут использовать stringstreams
для преобразования или просто старые atoi
.
enum
, cprogramming.com/tutorial/enum.html Таким образом, вы можете создать новый тип enum
котором каждое возможное значение является различным состоянием. В качестве альтернативы вы можете использовать int
и определять const
, например, 0
- первое состояние, 1
- второе, 2
- третье. Это (в некоторой степени) то, что enum
делает для вас.
while (!eof())
неверно.