I have searched many a site to find an answer to this question, so here goes:

I'm doing a hangman program that needs to pull different quotes from a text file named quotes.txt. Each quote is on a different line. I have the entire hangman program written (I can post later, if need be), but I need to write a function to get the quote, calculate the quote length, AND convert the entire quote to uppercase(I thnk I'm fine with that part though)

My variables are as follows:
(X is the length of the quote which will need to be calculated)
char realquote[x] contains the quote as it is written in the text file.
char quote[x] contains the quote written in all capitals

The function begins as follows:

void GetQuote()
{
   //This is where I need code to pull the quote
}

I will have approximately 10 quotes stored in the text file (One per line, as mentioned before). I would like to generate a random number between 1 and 10 and pull the quote from that line into the "realquote" array. I then need to determine the actual string length (I'm assuming I will use strlen or something like that?).

Any and all help with this would be greatly appreciated. Like I said, I can post up the entire Hangman program so you can see how it fits in, but I believe I've provided all relevant information to this specific part!

Thanks!
Madd0g

P.S. Right now I am using <stdio.h> <string.h> and <ctype.h> I can probably use some others (I'm using whatever comes with Visual Studio 2008) if I have to! Thanks again!

Recommended Answers

All 13 Replies

Take it one step at a time.
Start figuring how to generate the random number from one to ten.
After that lean how to open a file for reading.
Follow with reading a line from file and storing it in a buffer.
Once you got that down, you can start bringing all that knowledge to work together.

I know the random number should be something like: line = rand() % 10 + 1; the file open part should be:

FILE * pFile; 
pFile = fopen("quotes.txt","r");

(at least that's what the examples I've seen show)

then later on i'll need to close the file: fclose(pFile); The part I'm really struggling with is reading a line from the file and storing it into the arrays!

>The part I'm really struggling with is reading a line from the file and storing it into the arrays!
Alright! I think I have just what you need. Read on.

Ok...I now have this much:

void GetQuote()
{
	int whichquote;
	whichquote = rand() % 10 + 1;
	FILE*pFile;
	pFile = fopen("quotes.txt","r");
	
	if(pFile!=NULL) //IF FILE OPENS
	{
		while(fgets(quote, sizeof quote, pFile)!=NULL) 
		{
			fputs(quote,stdout);
		}
		fclose(pFile);
	}
       else
	{
		perror("quotes.txt");
	}
}

Now do I have to create a 2-D array and save all the quotes into there respective arrays, or can I fetch a different one from the text file later?

Also, is there a way to scan to see how many lines are in the text file so it can generate a random number based off of that?

I know this is not what you want to hear, but here it is nonetheless.
Go back to the example and study it a little more.
Create a text file and write on it a hundred times:
"Next time I will not copy and paste C code I don't understand."
Save the file with your choice of identifier.
Write a program that will open that file and display each line to standard output.
If you get stuck use your favorite search engine to find out more. Reading from file it is not a "strange" concept, therefore you are going to be lucking finding more than you need, all over the Internet or this site.
Once you have that part done. Report your progress over here.

Ok...I know this is a little bit of a change from what I state previously...After some thought, I've decided that what I really need is TWO functions. One that runs during the "setup" that puts all the different quotes into arrays, then a second function that I can use to return a quote whenever I need one.

The second function would be called in the form GetQuote(Number); where Number would be generated by rand() % TotalNumberOfQuotes + 1 . This function also needs to convert whatever quote it pulls to an identical quote but in all caps! (For example, if it pulls quote[]= "This is just a test." then it also needs to generate realquote[]="THIS IS JUST A TEST." ) The reason for this is because when the hangman program is checking to see if the letter the user guesses is in the phrase or if it's already been guessed, it compares everything versus the capital letters (otherwise 'A' and 'a' would be considered two different letters).

This being said, the first function would therefore need to assign each quote to an array as well as generate the total number of quotes. I imagine it would be a two-dimensional array such as array[a][b] where "b" is the line number, "a" is the actual quote.


BTW, here is my entire hangman program so far:

#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <windows.h>

char answer;
char quote[]; //Length determined by strlen?
char realquote[]; //Length determined by strlen?
int guessedquote[]; //Length determined by strlen?
char letters[26] = {'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};
int usedletters[26];
char guess;
int guesses;
int done;
int total;
int i,j;
int length;
int TotalQuotes;


char GetQuote()
{
	return(quote,realquote);
}

int RetrieveQuotes()
{

	return TotalQuotes;
}


char response() //Gets a single character response
{
	answer=getchar(); //Gets first character typed
	while(getchar()!='\n'){} //Waits for you to type the rest of your gibberish and press enter
	return answer; //Returns 'answer' as a character that can be compared too
}

void Reset() //DONE
{
	done = 0;
	guesses=7;
	for(i=0;i<26;i++)
	{
		usedletters[i]=0;
	}
	for(i=0;i<length;i++)
	{
		if(isalpha(quote[i]))
		{
			guessedquote[i]=0;
		}
		else
		{
			guessedquote[i]=1;
		}
	}
}

void PrintGuesses() //DONE
{
	printf("You have %i guesses remaining!\n",guesses);
}

void PrintPhrase() //DONE
{
	for(i=0;i<(length-1);i++)
	{
		if(guessedquote[i]==0)
		{
			printf("*");
		}
		else
		{
			printf("%c",realquote[i]);
		}
	}
	printf("\n");
}

void PrintLettersUsed() //DONE
{
	printf("Letters Used: ");
	for(i=0;i<26;i++)
	{
		if(usedletters[i]==1)
		{
			printf("%c ",letters[i]);
		}
	}
	printf("\n");
}
void PrintHangman()
{
	if(guesses==7)
	{
		printf("  _____ \n");
		printf(" /     |\n");
		printf(" |      \n");
		printf(" |      \n");
		printf(" |      \n");
		printf(" |      \n");
		printf(" |      \n");
		printf("_|_     \n");
	}
	if(guesses==6)
	{
		printf("  _____  \n");
		printf(" /     | \n");
		printf(" |     O \n");
		printf(" |       \n");
		printf(" |       \n");
		printf(" |       \n");
		printf(" |       \n");
		printf("_|_      \n");
	}
	if(guesses==5)
	{
		printf("  _____  \n");
		printf(" /     | \n");
		printf(" |     O \n");
		printf(" |     | \n");
		printf(" |       \n");
		printf(" |       \n");
		printf(" |       \n");
		printf("_|_      \n");
	}
	if(guesses==4)
	{
		printf("  _____  \n");
		printf(" /     | \n");
		printf(" |     O \n");
		printf(" |    \\| \n");
		printf(" |       \n");
		printf(" |       \n");
		printf(" |       \n");
		printf("_|_      \n");
	}
	if(guesses==3)
	{
		printf("  _____   \n");
		printf(" /     |  \n");
		printf(" |     O  \n");
		printf(" |    \\|/\n");
		printf(" |        \n");
		printf(" |        \n");
		printf(" |        \n");
		printf("_|_       \n");
	}
	if(guesses==2)
	{
		printf("  _____   \n");
		printf(" /     |  \n");
		printf(" |     O  \n");
		printf(" |    \\|/\n");
		printf(" |     |  \n");
		printf(" |        \n");
		printf(" |        \n");
		printf("_|_       \n");
	}
	if(guesses==1)
	{
		printf("  _____   \n");
		printf(" /     |  \n");
		printf(" |     O  \n");
		printf(" |    \\|/\n");
		printf(" |     |  \n");
		printf(" |    /   \n");
		printf(" |        \n");
		printf("_|_       \n");
	}
	if(guesses==0)
	{
		printf("  _____   \n");
		printf(" /     |  \n");
		printf(" |     O  \n");
		printf(" |     |  \n");
		printf(" |    \\|/\n");
		printf(" |     |  \n");
		printf(" |    / \\\n");
		printf(" |        \n");
		printf("_|_       \n");
	}
}


void GetLetter() //DONE
{
	int used = 0;
	printf("Your Guess: ");
	response();
	if(isalpha(answer))
	{
		guess = toupper(answer);
		for(i=0;i<length;i++)
		{
			if(quote[i]==guess)
			{
				guessedquote[i]=1;
				used=1;
			}
		}
		for(i=0;i<26;i++)
		{
			if((letters[i]==guess)&&(usedletters[i]==1))
			{
				printf("\nYou have already guessed that letter!");
				Sleep(1000);
				used=1;
			}
			if(letters[i]==guess)
			{
				usedletters[i]=1;
			}
		}
	}
	else
	{
		printf("That is not a letter!\n");
		Sleep(1000);
		used=1;
	}
	if(used==0)
	{
		guesses--;
	}
	total = 0;
	for(i=0;i<length;i++)
	{
		if(guessedquote[i]==1)
		{
			total++;
		}
	}
	if(total==length)
	{
		done = 1;
	}
}


void hangman() 
{
	Reset();
	system("cls");
	PrintHangman();
	PrintGuesses();
	PrintPhrase();	
	PrintLettersUsed();
	do
	{
		GetLetter();
		system("cls");
		PrintHangman();
		PrintGuesses();
		PrintPhrase();
		PrintLettersUsed();
	}
	while((guesses>0)&&(done==0));
	if(done==1)
	{
		printf("\nCongratulations! You have guessed the phrase!\n");
		printf("The phrase was: %s\n\n",realquote);
	}
	else
	{
		printf("\nSorry, you have run out of guesses! You have been HUNG!\n");
		printf("The phrase was: %s\n\n",realquote);
	}
	return;
}

int main(void) //MAIN PROGRAM LOOP
{
	printf("*NOTICE: ONLY THE FIRST CHARACTER YOU TYPE (FOR ANY RESPONSE) WILL BE USED!*\n\n");
	printf("Please press enter twice to continue...");
	while(response()!='\n') {}
	RetrieveQuotes();
	int Num;
	do
	{
		Num = rand() % TotalQuotes + 1;
		GetQuote(Num);
		hangman(); //Do Hangman Program
		printf("Would you like to play again? (Y/N) "); //Ask if you would like to repeat
		response(); //Get user response
		system("cls"); //Print user's answer so I know what it is!
	}
	while((answer=='Y')||(answer=='y'));
	system("cls");
	printf("Thank You for playing! Goodbye!\n\n"); //Dismiss user!
	return 0;
}

Did you learn how to read from file?

For simplicity purposes:

char quotes[3][12] = { "firstquote", "secondquote", "thirdquote" };
 int random_number = 1;
 printf("%s\n", quotes[random_number]);

Which quote would be displayed by printf? Maybe the answer would help you when the time comes to get the wanted quote.

That example should print "firstquote"

I'm going to post the code that was referenced in the thread you sent me to, adding in my comments for what each line is doing...Maybe you can help fill in the ??'s then!

int main ( void )
{
	static const char filename[] = "data.txt"; //Maddog - Sets the filename
	FILE *file = fopen ( filename, "r" ); //Maddog - Opens the file
	int i, j;
	char arra[128][128]; //Maddog - Initializes the array[][] variable and sets the size to 128x128
	char line[128]; /* or other suitable maximum line size */ //Maddog - Initializes a variable that will contain a single line

	for(i=0; i<128; i++) //Maddog - ???? It seems that he is setting everything in the array to '\0' (not sure why though)
	{
		for(j=0; j<128; j++)
		{
			arra[i][j] = '\0';
		}
	}

	for(i=0; i<128; i++) //Maddog - ???? Same as above, setting everything in the line array to '\0'
	{
		line[i] = '\0';
	}


	if ( file != NULL ) //Maddog - If files opens do...
	{
		i=0;
		//Maddog - ???? While not NULL (end of file??) get a line and the size of the line from the file
		while ( fgets ( line, sizeof line, file ) != NULL ) /* read a line */  
		{
			strcpy(arra[i], line); //Maddog - Copy string from the arra to line
			printf("array ----> %s ", &arra[i]); //Maddog - print the string you just pulled
			i++;
		}
		fclose ( file ); //Maddog - Close file
	}
	else //Maddog - If file doesn't open...
	{
		perror ( filename ); /* why didn't the file open? */ //Maddog - Spit out error message to tell you that file didn't open
	}
	return 0;
}

That example should print "firstquote"

Close, but no cigar. "secondquote" is the correct answer. You forgot that subscript starts at zero.
Anyway, what I am trying to show you is that you can access quotes by its subscript.
Variable names are for clarification purposes:

char hidden_quotes[amount_quotes][given_length]; /* you don't know which quote */
int random_number; /* generated later */
...
...
size_t len = strlen(hidden_quotes[random_number]); /* quotes length */
for( i = 0; i < len; i++) {
/* make the quote upper case using toupper(), include ctype.h for that */   
   hidden_quotes[random_number][i] = toupper(hidden_quotes[random_number][i]);
}

Let's start here: char arra[128][128]; Putting object concepts to it, that tells me you are setting memory for 128 quotes of 128 maximum length, each quote.
I thought you wanted to read only ten quotes from file.
char arra[10][128];

for(i=0; i<128; i++) //Maddog - ???? It seems that he is setting everything in the array to '\0' (not sure why though)
	{
		for(j=0; j<128; j++)
		{
			arra[i][j] = '\0';
		}
	}

(not sure why though)--> Because you are iterating through each character of each quote and setting it up to null.

arra[0][0] = '\0';
arra[0][1] = '\0';
...
arra[1][0] = '\0';
arra[1][1] = '\0';
...

Ok...so I changed my GetQuote() fuction to:

void GetQuote()
{
	int number;
	number = rand() % 10 + 1; //Generates a random number from 1 to 10

	size_t length = strlen(quotearray[number]); //Gets length of string
	
	for(i=0;i<length;i++) //For the entire length of the quote
	{
		quote[i]=toupper(quotearray[number][i]); //Convert the quotearray[] to uppercase and store in quote[]
	}
}

I'm gonna work on the RetrieveQuotes() function now, though I might have to wait until after work!

Let's start here: char arra[128][128]; Putting object concepts to it, that tells me you are setting memory for 128 quotes of 128 maximum length, each quote.
I thought you wanted to read only ten quotes from file.
char arra[10][128];

I do want only 10 quotes(of 100 characters each actually), but I was just using his example which was 128x128

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.