I'm working on a project that's the final part of something some of you tried to help me with last week. Now, I'm supposed to not only read a file into an array and prompt the user for information, but also display the completed story and ask the user if they want to play again. I'm getting weird results when my program tries to display the story, and I'm not sure why. Here are my test results:
Starting Test 1
The first test is trivial:
My pet cat is very <{> <adjective> . <}> <#> So is my dog . <#>
> Please enter the filename of the Mad Lib: /home/cs124/projects/madLibTrivial.txt
> Adjective: happy
>
> My My pet pet pet cat cat cat is is very very very very "happyhappyhappyhappyhappy" So So is is my my dog dog dogDo you want to play again (y/n)?
Exp: My pet cat is very "happy."\n
Timed out!
My code is below. I would really appreciate any help you can give. I've tried to find a tutor, but since it's late in the semester and it's the holidays, it's hard to find one.
/***********************************************************************
* Program:
* Project 10, Mad Lib Program
* Sister Unsicker, CS124
* Author:
* Lanie Molinar
* Summary:
* This program is the final part of the Mad Lib project. It reads the Mad
* Lib from a file, making sure it's the right size, and prompts the user
* for words or phrases to fill in the needed text. It then displays the
* completed story.
*
* Estimated: 10.0 hrs
* Actual: 20.0 hrs
* I could never get it to work, even though I followed the pseudocode and
* got tutoring twice.
************************************************************************/
#include <iostream>
#include <fstream>
#include <cctype>
#include <cstring>
usingnamespace std;
/***********************************************************************
* This function gets the file name from the user and passes it to the other
* functions.
***********************************************************************/
void getFilename(char fileName[])
{
cout << "Please enter the filename of the Mad Lib: ";
cin >> fileName;
cin.ignore();
}
/***********************************************************************
*This function turns the prompts in the file into questions and asks the user
* for the information.
***********************************************************************/
void askQuestions(char story[])
{
if (story[0] != '<' || !isalpha(story[1]))
return;
else
{
story[1] = toupper(story[1]);
cout << "\t" << story[1];
for (int iStory = 2; story[iStory] != '>'; iStory++)
{
if (story[iStory] == '_')
cout << " ";
else
{
story[iStory] = tolower(story[iStory]);
cout << story[iStory];
}
}
cout << ": ";
cin.getline(story, 256);
}
}
/***********************************************************************
* This function reads the Mad Lib file and passes information to the
* askQuestions function.
***********************************************************************/
int readFile(char story[][33], char fileName[])
{
ifstream fin(fileName);
if (fin.fail())
{
cout << "Error reading file " << fileName << ".\n";
return 0;
}
int numWords = 0;
while (fin >> story[numWords])
{
askQuestions(story[numWords]);
numWords++;
}
if (numWords > 256)
{
cout << "Error reading file " << fileName
<< ". It has more than 256 words.";
return 0;
}
fin.close();
cout << endl;
return numWords;
}
void displayStory(int wordCount, char story[][33])
{
for (int numWords = 0; numWords < wordCount; numWords++)
{
for (int iStory = 0; iStory < strlen(story[numWords]); iStory++)
{
char character = story[numWords][iStory];
if (isalpha(story[numWords][0]))
{
if (story[numWords - 1][1] != '{' && story[numWords - 1][1] != '[')
cout << " " << story[numWords];
else
cout << story[numWords];
}
if (character != '<' && character != '>' && !isalpha(character))
{
switch (character)
{
case'#':
character = '\n';
break;
case'{':
character = '\"';
cout << " " << character;
break;
case'}':
character = '\"';
cout << character;
break;
case'[':
character = '\'';
cout << " " << character;
break;
case']':
character = '\'';
cout << character;
}
}
}
}
}
char playAgain()
{
char cont;
cout << "Do you want to play again (y/n)?";
cin >> cont;
while (cont != 'n' && cont != 'N' && cont != 'y' && cont != 'Y')
{
cout << "Invalid input. Please enter y/n.\n"
<< "Do you want to play again (y/n)?";
cin >> cont;
}
return cont;
}
/**********************************************************************
* The main function calls the getFilename and readFile functions.
***********************************************************************/
int main()
{
char story[256][33];
char fileName[256];
getFilename(fileName);
int wordCount = readFile(story, fileName);
displayStory(wordCount, story);
char cont = playAgain();
while (cont != 'n' && cont != 'N')
{
getFilename(fileName);
wordCount = readFile(story, fileName);
displayStory(wordCount, story);
cout << "\nThank you for playing.\n";
return 0;
}
}
First I would suggest that you initialize all your variables when you define the especially the arrays. Using {} after the variable name or after the last [] of an array will set everything to zero for most variable types, for a "char" it is "\0".
The double output you are getting is the nested for loops in the display function. I commented out the outer for loop and defined the variable size_t numWords{};. The "size_t" is another name for "unsigned int". At the end of the for loop I added numWords++;.
Before I made the last post the program ran the way it should unless I misread something. After I made the post when I went back to the program it would only print the first three words and then stop. Still trying to figure what went wrong.
Sorry to get your hopes up and the inconvenience. I will figure this out eventually.