I need to have a user input a word then compare the word with a text file to see if it is correct. The user has 3 attempts to enter the word before the program terminates. My issue is reading the word from the file I know it's something simple that I have wrong. I should also clarify that the error I'm getting is in the compiler I haven't gotten to the point of being able to compare the strings yet!
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(void)
{
FILE *fp;
fp = fopen("secret.txt","r");
char guess[10];
const char secret[10];
int i, c;
c = getc(fp);
fgets(secret, sizeof(secret), fp);
for (i=0; i < 3; i++)
{
printf("Please guess the word: \n");
scanf("%s", guess);
while (c !=EOF)
{
if (strcmp(secret,guess)==0)
{
printf("Your guess was correct");
return 0;
}
else
{
printf("Your guess was incorrect. Please try again\n");
}
}
fclose (fp);
}
return 0;
}
Here are some pointers:
c = getc(fp) consumes the first character of the file, so it never becomes part of the secret variable.
If secret.txt contains a newline, the newline is read into the secret variable.
The while (c != EOF) loop seems pointless, since c isn't modified inside the loop. Furthermore, the infinite nature of the loop prevents the outer for loop from functioning correctly.
If I were you, I'd fix the while loop and would make sure that secret is read correctly, for example by printing it out or examining it in a debugger.
What is
c = getc(fp);
needed for? My "guess" would be that you read the first character of the word into c and then secret misses the first character.
EDIT: Instead of using getc for EOF checking, which as said corrupts the read word (and this while loop is rubbish anyway), just check the return value of fgets:
if(fgets(secret, sizeof(secret), fp) == NULL)
//file is empty or other error occurred
and remove this infinite while(c != EOF) loop.
So it should rather look something like:
FILE *fp = fopen("secret.txt","r");
char guess[10];
const char secret[10];
int i;
if(fgets(secret, sizeof(secret), fp) == NULL)
{
printf("Error while reading file\n");
return -1;
}
fclose(fp);
for (i=0; i < 3; i++)
{
printf("Please guess the word: \n");
scanf("%s", guess);
if (strcmp(secret,guess) == 0)
{
printf("Your guess was correct");
return 0;
}
else
printf("Your guess was incorrect. Please try again\n");
}
return 0;
Your code is grossly off: you do not alter 'c' inside a loop, making it spin indefinitely. It's a good idea to sketch your algorithm on a piece of paper before you start coding. In your case, pseudocode should look like this:
Open file
Read the secret
Close file
Repeat three times:
--- Display the prompt
--- Read user input
--- If user input matches the secret, congratulate the user and exit.
Tell the user his guess was incorrect.
At this point, converting it to C should be more or less mechanical. Good luck!
while (c !=EOF)
{
if (strcmp(secret,guess)==0)
{
printf("Your guess was correct");
return 0;
}
else
{
printf("Your guess was incorrect. Please try again\n");
}
}
looks like an infinite loop to me
Related
I am trying to make a simple code that will read a char from input and execute "Correct" or "Incorrect input" and run the code again until the correct input is entered. First of all it does not work for capital X. The other issue that I want to fix is that after the incorrect input I have to press enter to get the "Enter x" message, instead of getting in immediately after the incorrect input message.
#include <stdio.h>
int main()
{
do
{
printf("Enter x\n");
if (getchar()=='x'|| getchar()=='X')
{
printf("Entered char is X\n");
return 0;
}
else
{
printf("Input incorrect! Please try again!!!\n");
}
}
while (getchar()!='x' || getchar()!='X');
return 0;
}
You need to store the input in a variable, otherwise you keep asking for input several times in a row, for each getchar call.
For weird historic reasons, getchar actually returns an int, since the value EOF that can be returned from it is an int. So the variable must be int.
And finally, each time the user hits enter, a invisible line feed character \n is appended to the input stream. This character does you no good, so you should discard it with an extra read.
#include <stdio.h>
int main (void)
{
int input;
do
{
printf("Enter x\n");
input = getchar();
getchar(); // extra getchar to chew up line feed from stdin
if (input=='x'|| input=='X')
{
printf("Entered char is X\n");
}
else
{
printf("Input incorrect! Please try again!!!\n");
}
} while (input!='x' && input!='X');
return 0;
}
Please note that the opposite of input=='x'|| input=='X' is input!='x' && input!='X' (De Morgan's laws). "If input is not 'x' and input is not 'X' then loop".
When you hit the ENTER key the newline character \n is placed in input buffer. You need to consume that newline character in order to read the next character.
Also you are reading two time, which is unnecessary in this case. So your code should be like this
#include <stdio.h>
int main()
{
char inp;
do
{
printf("Enter x\n");
inp = getchar();
getchar(); // reading the newline character '\n'
if (inp == 'x'|| inp =='X')
{
printf("Entered char is X\n");
return 0;
}
else
{
printf("Input incorrect! Please try again!!!\n");
}
}
while (inp !='x' || inp !='X');
return 0;
}
p.s There is no need to put condition checking in while loop, since you are returning in if condition. while(true) would work fine. Thanks #bruno for pointing that out.
In your code:
if (getchar()=='x'|| getchar()=='X')
getchar() is called twice.
Instead, you should write it this way:
char c = getchar();
if (c=='x'|| c=='X')
for the second part, if your goal is print the message on a new line, then just simply change your printf to:
printf("\nInput incorrect! Please try again!!!\n");
If I only want the user to enter one char, how would I go about doing that in the c language. My attempt at this is below but it failed horribly. From what i read online I heard you could use the function gets or fgets to accomplish this, but I could not figure out how.
do
{
geussNumber += 1;
printf("Enter guess number %d\n", geussNumber);
scanf(" %c", &geussLetter);
scanf ("%c", &inputViolation);
if (isalpha(geussLetter) == 0)
{
printf("You did not enter a letter\n");
}
else if (inputViolation == true)
{
printf("You eneterd more than one letter\n");
}
else
{
inputLoopEnd = 1;
}
}
while( inputLoopEnd == false );
You could use the getc family of functions.
Have a look at http://quiz.geeksforgeeks.org/difference-getchar-getch-getc-getche/ for example.
It seems you want to read input one line at a time (i.e. the user types a one-letter guess and then <enter>), and you want to verify that the guess indeed contains only a single letter. Couching the problem in those terms perhaps makes it clearer how fgets() could be applied, as that function's purpose is to read one line at a time. Having read a whole line -- or at least as much as the buffer can accommodate -- you can validate it and extract the guess.
scanf() is hard to use properly, so I do recommend the fgets() approach. If you insist on using scanf(), however, then you might do it like this:
// consumes leading whitespace, inputs one character, then consumes any
// immediately-following run of spaces and tabs:
int result = scanf(" %c%*[ \t]", &guessLetter);
if (result == EOF) {
// handle end-of-file ...
} else {
assert(result == 1); // optional; requires assert.h
int nextChar = getchar();
if ((nextChar == '\n') || (nextChar == EOF)) {
// handle multiple-character guess ...
} else if (!isalpha(guessLetter)) {
// handle non-alphabetic guess ...
} else {
// it's valid ...
}
}
Do not use things like fgets() or fputs() etc... They are falling out of use.
As you can see from the description here... this function is designed to handle objects of type str, and you are more focused on using chars at the moment so why not just handle only chars to make life easier.
You can't do this the way you think you can...
scanf(" %c", &geussLetter);
scanf ("%c", &inputViolation);
This can't work because even if the user enters in only one char the way they are supposed to, it's still going to trigger your inputViolation scheme.
Edit: 12:14pm 7/20/2016
I really like the elegance of MOHAMAD's solution on the community wiki.
So I edited to fit your situation and it works well here too. Same idea...
#include <stdio.h>
#include <stdlib.h>
int clean_stdin()
{
while (getchar() != '\n');
return 1;
}
int main(void)
{
int first_time_around = 0;
char theguess = 0;
char c;
do
{
if (first_time_around == 0)
first_time_around++;
else
printf("Wrong input \n");
printf("Enter guess number: \n");
} while (((scanf("%c%c", &theguess, &c) != 2 || c != '\n')
&& clean_stdin()) || !isalpha(theguess));
return 0;
}
My program is designed to sort records in a text file, but my main issue is getting the main function to ask the user if he would like to run the program again to read and write another file. My program right now, when the user enters 1 to run again, skips the first question to enter the program to read. Why is that? I appreciate the help! Here is my main function only: The program compiles only during the first run.
int main()
{
int fieldCount = 0;
int lineCount = 0;
char file[STR_LEN];
char filepath[STR_LEN];
char** fields = NULL;
char** lines = NULL;
int recCount = 0;
Person **sortedRecs = NULL;
int x;
do {
printf("Enter path of the file to read: ");
gets(filepath);
printf("Enter path to copy to: ");
gets(file);
fields = readFieldsDynamic(filepath, &fieldCount);
lines = readLinesDynamic(filepath, &lineCount);
recCount = getPersons(fields, fieldCount, &sortedRecs);
if (recCount && lines && sortedRecs && (recCount <= lineCount)) {
writeRecsToFile(file, sortedRecs, recCount, lines, lineCount);
printf("Sorted records are written in %s\n", file);
}
if (fields) {
freePointerToChars(fields, fieldCount);
}
if (lines) {
freePointerToChars(lines, lineCount);
}
if (sortedRecs) {
freeRecs(sortedRecs, recCount);
}
printf("Enter 1 to run program again: ");
scanf("%d%*c", &x);
} while (x == 1);
return 0;
}
What you can do is add a while loop to "eat up" all the newlines left in stdin stream to prevent the next getchar to not block for real user input.
while ((ch=getchar()) != EOF && ch != '\n')
;
Also please don't use gets in your code. Try fgets instead.
You need to keep a space before %c.
int main()
{
char ch;
do
{
something();
printf("\nDo you want to continue?");
scanf(" %c", &ch);
}while(ch=='y');
return 0;
}
This answer is based on your output looking something like:
Enter path of the file to read: /my/input/here/
Enter path to copy to: /blah/copy/here/
Enter 1 to run program again: 1
Enter path of the file to read:
Enter path to copy to: help/I/cant/type/in/the/above/field
My understanding is your program is probably carrying over the newlines between loops.
I've had similar problems in C++, and placing cin.get() after an input fixed it. I'm not certain of the C equivalent.
I'm currently working on a program that asks a user to enter a secret word. The user's input is then compared with a list of words which are on a text file. The user has 3 chances to enter the word. If correct, the program restarts the loop. This continues until all the words have been guessed correctly. If a word is incorrectly guessed 3 times, the program should terminate. My problem is with the 3 guesses loop. I can get it to work if it is not nested in the while loop however with the while loop it's continues to ask for the incorrect word. What am I missing? Here is my code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(void)
{
//Step 1: open file and declare variables//
FILE *fp;
fp = fopen("secretwords.txt","r");
char guess[20];
char secret[20];
int i;
//Step 2: Check that file opened correctly, terminate if not//
if (fp == NULL)
{
printf("Error reading file\n");
exit (0);
fclose(fp);
}
//Step 3: Create loop to run for each word to run to end of file//
while(fscanf(fp,"%s", secret)!=EOF)
{
for (i=0; i < 3; i++)
{
printf("Please guess the word: \n");
scanf("%s", guess);
if (strcmp(secret,guess)==0)
{
printf("Your guess was correct\n");
break;
}
else
{
printf("Your guess was incorrect. Please try again\n");
}
}
}
return 0;
}
When you do break, you break from the for loop, but not from the while loop.
To solve it, you can either change the design to have one loop only, or you should have the break instruction in the outer loop too.
You did not do break in the following part:
else
{
if(i == 2)
break;
printf("Your guess was incorrect. Please try again\n");
}
Hint: if the user has had 3 misses, the value of i after the for loop will equal to 3. This is your chance to do something (terminate the program).
I'm creating a program that asks the user to input a word. The word is then compared with a word in a text file. If correct, I want the user to input another word which should correspond with the next word in the text file and this should loop until the end of the file. I'm having trouble with the loop to the end of the file. Could someone please review my code and give me a few pointers? thanks so much
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(void)
{
//Step 1: open file and declare variables//
FILE *fp;
fp = fopen("secretwords.txt","r");
char guess[20];
char secret[20];
int i, count;
//Step 2: Check that file opened correctly, terminate if not//
if (fp == NULL)
{
printf("Error reading file\n");
exit (0);
fclose(fp);
}
//Step 3: Create loop to run for each word to run to end of file//
fscanf(fp,"%s", secret);
//Need to create a loop here that will read the text file 20 times,
// each time reading the next word//
for (i=0; i < 3; i++)
{
printf("Please guess the word: \n");
scanf("%s", guess);
if (strcmp(secret,guess)==0)
{
printf("Your guess was correct\n");
return 0; //This return will terminate the program.
// I need to restart loop from here
}
else
{
printf("Your guess was incorrect. Please try again\n");
}
}
return 0;
}
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(void)
{
FILE *fp = fopen("secretwords.txt", "r");
if (fp == NULL)
{
printf("Error reading file\n");
return 1;
}
char guess[20] = {0};
char secret[20] = {0};
while(fscanf(fp, "%s", secret) != EOF) // i would suggest you use 'fscanf_s("%s", guess);' instead if available
{
printf("Please guess the word: \n");
scanf("%s", guess); // i would suggest you use 'scanf_s("%s", guess);' instead if available
if (!strncmp(secret, guess, sizeof(guess)))
{
printf("Your guess was correct. Continue ...\n");
}
else
{
printf("Your guess was incorrect. Good bye.\n");
break;
}
}
fclose(fp);
return 0;
}
i made some suggestions about scanf_s and fscanf_s, if they are available, use them. But still, i am wondering why they are still teaching bad code in schools? I would not suggest to use *scanf* functions at all. Further reading: uncontrolled format string
Move the fscanf call that reads from the file to a function that returns the next word
loop for user input, only calling the function outlined above when you need to advance to the next word in the file (when the user inputs the correct thing)