I'm not going to write code for you (since this is clearly a homework problem), but I will offer some suggestions as to how I would do this completely differently. Hope this pseudo code helps.
EDIT: I missed the logic for AVERAGE and how the score should work, I'm making some corrections. (Note, with these changes, it may be better to add new states. I would consider Normal, Name, BeginAverage, Average, EndAverage. But it's up to you.)
1) Define these states (use an enum perhaps):
- Normal (there's probably a better name for this one)
- Name
- Average
2) You want to read one "token" and transition with the following rules. Note that a token in this case will be a string, separated by spaces (e.g. "NAME", "AVERAGE", "Bob", "11", "23").
- If state is Normal (this is also the initial state)
- If token is "NAME", go to state Name
- If token is "AVERAGE", go to state Average
- If token starts with one of these characters '0', '1', '2', ... '9', convert it to a double and add it to your score
- If state is Name
- Copy the token into your "name" variable, transition back to Normal state
- If state is Average
- If you get a number, add it to a temporary count and increment a counter
- If you get a string that is not "NAME", "AVERAGE", or a number, go back to Normal state
- If you get "NAME", go to Name state
- Before you enter this state, you need to reset your temporary count/counter to calculate the average
- Before you leave this state, calculate the average and add it to the total score
3) For processing the input, read everything into a string variable first. Then you can use stringstream
s to convert to double when needed. Just read all of the strings (tokens) as I've described and process them as above until you reach EOL.
"Code":
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
takes a string and can just check that the first character is a number ('0', '1',...). It could be fancier and look at each character for numbers/decimals.
convertToNumber
takes a string and converts to a double. Could use stringstreams
to do the conversion or just the old atoi
.