So here is my code:
#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#define MAX_GUESSES 4
int PlayGame(char guess);
int WinOrLose(char userguess, char solution);
int main()
{
FILE* infile;
char correctlet;
int games,
igame,
result;
infile = fopen("inputLet.txt", "r");
printf ("Welcome to the letter guessing game!\n");
printf ("Your job is to guess a random letter.\n");
printf("You can guess each letter a maximum of 4 times,\n");
printf ("and you will get a hint after every guess.\n");
printf ("LET'S DO THIS!\n\n>");
printf ("\nHow many games would you like to play (1-3)?\n>");
scanf ("%d",&games);
for(igame=0;igame<games;igame++)
{
fscanf(infile," %c",&correctlet);
printf("This is game %d\n", igame+1);
result = PlayGame (correctlet);
if (result == 0)
{
printf ("\nCongratulations, you guessed the right letter!\n");
}
else
{
printf ("\nUnfortunately, you did not guess the right letter. Better luck next time!\n");
}
}
return 0;
}
int PlayGame(char solution)
{
int guessnumber,
result;
char userguess;
guessnumber = 0;
while(guessnumber < MAX_GUESSES)
{
printf("Please enter your guess\n>");
scanf("%c", &userguess);
if (sizeof userguess == 0)
{
continue;
}
else if (sizeof userguess >=1)
{
printf ("Your guess was %c\n",userguess);
result = WinOrLose (userguess, solution);
if (result == 0)
{
return 0;
break;
}
else if (result == 1)
{
if (solution < userguess)
{
printf("The correct letter comes before %c alphabetically\n", userguess);
}
else if (solution > userguess)
{
printf("The correct letter comes after %c alphabetically\n", userguess);
}
guessnumber ++;
}
}
}
}
int WinOrLose (char userguess, char solution)
{
if(solution==userguess)
{
return 0;
}
else if (solution != userguess)
{
return 1;
}
}
The output asks for the number of games, and then it outputs please enter your guess your guess was (blank) The correct letter comes after (blank) Please enter your guess and THEN it allows for user input. So why is it going through one iteration of PlayGame without asking for user input? I have tried everything I can think of and can't fix the problem. I am compiling on VC++ 2010, if that helps.
Thanks in advance!
The simple answer is to flush your buffers.
The stdin buffer, the buffer that takes instructions from the keyboard (or a pipe) and submits it to the program occasionally gets some characters "stuck" in it. Junk characters that never quite get submitted, extra returns, etc. that will cause scanf() to think it reached the proper end, but actually hasn't.
fflush(stdin);
The function fflush "flushes" a buffer. The effect of this is to consume data from a buffer until the data received is the character '\0' (NULL). This means that it's reached the last of the data that is currently in the buffer.
Calling this before calling scanf() means that when scanf() is called, you reasonably know that the program will block on scanf() until you've submitted, and not just consume some junk from the buffer.
Related
i am pretty new to c, i m trying to make the user input a number, but if they input a letter or word it shows a warning and asks for input again, my code works fine if the user puts in a number but it goes into an infinite loop if the user inputs something invalid, here is my code
#include <stdio.h>
int main(void) {
float salary;
int status = 0;
while (status == 0)
{
printf(" Please input your yearly salary to calculate taxes: \n");
status = scanf(" %f", &salary);
if (status == 0)
printf("invalid input!\n");
}
printf("%.2f\n", salary);
return 0;
}
i thought that i was something to do with the buffer left over from the first scanf , but adding a space " %f" didnt work, i tried using fflush(stdin) after then scanf also didnt work. i m not sure what else i can try.
thanks in advance for any help.
You need to clear the buffer or it will keep evaluating it and cause the endless loop. Add one line after your invalid input: scanf("%*[^\n]")
#include <stdio.h>
int main(void) {
float salary;
int status = 0;
while (status == 0)
{
printf(" Please input your yearly salary to calculate taxes: \n");
status = scanf(" %f", &salary);
if (status == 0)
printf("invalid input!\n");
scanf("%*[^\n]");
}
printf("%.2f\n", salary);
return 0;
}
This will work. You can see a better explanation here: Scanf and loops
The problem is that scanf won't advance the file stream. You ask it to read a floating point value and it isn't able to, so it doesn't consume the input.
For example, let's say your input is "foo", which isn't a number. Your scanf call isn't able to successfully read anything and returns 0. Then, in the next iteration, "foo" is still waiting to be read from stdin.
Try changing your if condition to something like
if (status == 0) {
char foo[256];
fgets(foo, sizeof(foo), stdin);
printf("Invalid input! Expected a nmuber, got: %s", foo);
}
Notice how the entire input is read from stdin by the gets call.
I've just started learning the language of C, and would love your help in cleaning up / simplifying my code if you know a better way to reach the following.
I want a program to ask for a number, and if that is found then proceed to print and end, however if anything else is put in (e.g. a letter key), then I want the program to loop asking for a number until one is given.
I started off by using a simple scanf input command, but this seemed to go into an infinite loop when I tried to check if a valid number (as we define them) was put in.
So instead I have ended up with this, from playing around / looking online, but I would love to know if there is any more efficient way!
//
// Name & Age Program
// Created by Ben Warren on 1/3/18.
//
#include <stdio.h>
int main (void)
{
//Setting up variables
int num;
char line[10]; /* this is for input */
//Collecting input
printf("Please enter any number? \t");
scanf("%d", &num);
//If Invalid input
while (num==0)
{
printf("\nTry again:\t");
fgets(line, 10, stdin); //turning input into line array
sscanf(line, "%d",&num); //scaning for number inside line and storing it as 'num'
if (num==0) printf("\nThat's not an number!");
}
//If Valid input
{
printf("\n%d is nice number, thank you! \n\n", num);
*}*
return 0;
}
Instead of checking if the value is different to 0, check the return value of
sscanf. It returns the number of conversions it made. In your case it should be 1. Unless the return value is 1, keep asking for a number.
#include <stdio.h>
int main(void)
{
int ret, num;
char line[1024];
do {
printf("Enter a number: ");
fflush(stdout);
if(fgets(line, sizeof line, stdin) == NULL)
{
fprintf(stderr, "Cannot read from stdin anymore\n");
return 1;
}
ret = sscanf(line, "%d", &num);
if(ret != 1)
fprintf(stderr, "That was not a number! Try again.\n");
} while(ret != 1);
printf("The number you entered is: %d\n", num);
return 0;
}
That is not a bad approach for someone new to C. One small improvement would be to actually check the return value of scanf(), since it returns the number of arguments successfully retrieved. Then you could get away from relying on num being 0 to indicate the input was valid. Unless you do want to specifically flag 0 as invalid input.
int ret = scanf("%d", &num);
ret == 1 would mean an integer was succesffully read into num, ret == 0 would mean it was not.
Consider using strtol to parse a string for a long int. This also allows you to detect trailing characters. In this example if the trailing character is not a newline, the input can be rejected. strtol can also detect overflow values. Read the documentation to see how that works.
#include <stdio.h>
#include <stdlib.h>
int main (void)
{
//Setting up variables
long int num = 0;
char line[40] = ""; /* this is for input */
char *parsed = NULL;
printf("Please enter any number? \t");
fflush ( stdout);
while ( fgets(line, 40, stdin))
{
parsed = line;//set parsed to point to start of line
num = strtol ( line, &parsed, 10);
if ( parsed == line) {//if parsed equals start of line there was no integer
printf("Please enter a number? \t");
printf("\nTry again:\t");
fflush ( stdout);
continue;
}
if ( '\n' != *parsed) {//if the last character is not a newline reject the input
printf("Please enter only a number? \t");
printf("\nTry again:\t");
fflush ( stdout);
}
else {
break;
}
}
if ( !parsed || '\n' != *parsed) {
fprintf ( stderr, "problem fgets\n");
return 0;
}
printf("\n%ld is nice number, thank you! \n\n", num);
return 0;
}
0 (zero) is a number...
But I see what you want to do...
You can check for a valid number, using isdigit or a combination of similar functions
I think its also important to follow the advice of other answers to use the return value from scanf using code such as:
int ret = scanf("%d", &num);
and examining ret for success or failure of scanf.
I'm trying to create a program that asks to type something and check if it is an integer. If it is an integer, then print "the integer is ...". Else, print "try again" and waits for another input. However, the program prints an infinite number of "try again" if you type in a character. Here's the source code:
#include <stdio.h>
#include <stdbool.h>
int main()
{
int inp;
bool t = 1;
printf("type an integer\n");
while (t) {
if (scanf("%i", &inp) == 1) {
printf("The integer is %i", inp);
t = 0;
} else {
printf("try again");
scanf("%i", &inp);
}
}
}
OP's code fail to consume the offending non-numeric input. It remains in stdin, for the next input function. As it is unfortunately just another scanf("%i", &inp) which fails the same way - infinite loop.
After attempting to read an int, read the rest of the line.
#include <stdio.h>
#include <stdbool.h>
int main() {
int inp;
int scan_count;
printf("Type an integer\n");
do {
scan_count = scanf("%i", &inp); // 1, 0, or EOF
// consume rest of line
int ch;
while ((ch == fgetchar()) != '\n' && ch != EOF) {
;
}
} while (scan_count == 0);
if (scan_count == 1) {
printf("The integer is %i\n", inp);
} else {
puts("End of file or error");
}
}
An even better approach would read the line of user input with fgets(). Example
When you entered a char, the variable inp in scanf("%d", &inp) would get null, since the input that doesn't match the format string. And the character you input would remain in the buffer, so that's the reason both your scanf would not stop.
A simplest way to fix this is modify your second scanf("%i", &inp); to scanf("%c", &c); (don't forget to declare a char c in your main function).
check here while(t) its in an infinite loop because you have to set a condition for t something like while(t==1) or while(t>1) or (t<1) something like that. saying while(t) means that t can be anything and it will continue to run.
There is nothing in to break the while loop.
consider getting rid of the boolean, and simply using a while (1) loop with a break. Also you should be using "%d" to indicate an integer in scanf/printf. And there is no need for the scanf call in the else, since your program would loop back and call scanf again anyway.
#include <stdio.h>
int main() {
int inp = 0;
printf("type an integer\n");
while (1) {
if (scanf("%d", &inp) == 1) {
printf("The integer is %d", inp);
break;
}
else {
printf("try again");
}
}
return 0;
}
I hope this helped.
I was working on this sample exercise, and everything works as I would like it to, but there is one behavior I don't understand.
When providing input: if I make consecutive invalid entries everything seems to work great. But if I enter a number different from 1,2,3 in the case of the first question, or 1,2 in the case of the second question, the program just sits there until a new input is given. If another invalid entry is made, it goes back to the error "invalid entry" message, and if an appropriate number is entered, everything moves along fine.
I do not understand why it stops to wait for a second input...anyone?
Thanks guys.
#include <stdio.h>
static int getInt(const char *prompt)
{
int value;
printf("%s",prompt);
while (scanf("%d", &value) !=1)
{
printf("Your entry is invalid.\nGive it another try: %s", prompt);
getchar();
scanf("%d", &value);
}
return value;
}
int main() {
int wood_type, table_size, table_price;
printf("Please enter " );
wood_type = getInt("1 for Pine, 2 for Oak, and 3 for Mahogany: ");
printf("Please enter ");
table_size = getInt("1 for large, 2 for small: ");
printf("\n");
switch (wood_type) {
case 1:
table_price = (table_size == 1)? 135:100;
printf("The cost of for your new table is: $%i", table_price);
break;
case 2:
table_price = (table_size == 1)? 260:225;
printf("The cost of for your new table is: $%i", table_price);
break;
case 3:
table_price = (table_size == 1)? 345:310;
printf("The cost of for your new table is: $%i", table_price);
break;
default:
table_price = 0;
printf("The cost of for your new table is: $%i", table_price);
break;
}
}
You most likely need to flush your input buffer (especially with multiple scanf calls in a function). After scanf, a newline '\n' remains in the input buffer. fflush does NOT do this, so you need to do it manually. A simple do...while loop works. Give it a try:
edit:
static int getInt(const char *prompt)
{
int value;
int c;
while (printf (prompt) && scanf("%d", &value) != 1)
{
do { c = getchar(); } while ( c != '\n' && c != EOF ); // flush input
printf ("Invalid Entry, Try Again...");
}
return value;
}
The blank line you get if you enter nothing is the normal behavior of scanf. It is waiting for input (some input). If you want your routine to immediately prompt again in the case the [Enter] key is pressed, then you need to use another routine to read stdin like (getline or fgets). getline is preferred as it returns the number of characters read (which you can test). You can then use atoi (in <stdlib.h>) to convert the string value to an integer. This will give you the flexibility you need.
example:
int newgetInt (char *prompt)
{
char *line = NULL; /* pointer to use with getline () */
ssize_t read = 0; /* number of characters read */
size_t n = 0; /* numer of chars to read, 0 no limit */
static int num = 0; /* number result */
while (printf ("\n %s ", prompt) && (read = getline (&line, &n, stdin)) != -1)
{
if ((num = atoi (line)))
break;
else
printf ("Invalid Input, Try Again...\n");
}
return num;
}
If some invalid input is entered, it stays in the input buffer.
The invalid input must be extracted before the scanf function is completed.
A better method is to get the whole line of input then work on that line.
First, put that input line into a temporary array using fgets(),
then use sscanf() (safer than scanf because it guards against overflow).
#include <stdio.h>
int main(int argc, const char * argv[]) {
char tempbuff[50];
int result, d , value;
do
{
printf("Give me a number: ");
fgets( tempbuff, sizeof(tempbuff), stdin ); //gets string, puts it into tempbuff via stdin
result = sscanf(tempbuff, "%d", &value); //result of taking buffer scanning it into value
if (result < 1){ //scanf can return 0, # of matched conversions,
//(1 in this case), or EOF.
printf("You didn't type a number!\n");
}
}while (result < 1);
//some code
return 0;
}
Knowledge from: http://www.giannistsakiris.com/2008/02/07/scanf-and-why-you-should-avoid-using-it/
I'm having a problem with scanf freezing. I've looked around and while some questions are similar, they haven't helped in solving my problem.
main(int argc, char **argv) {
//FILE *stream = stdin;
if (stdin == NULL) {
printf("Could not open file");
return 0;
}
int exists = 0;
char letter;
char next = 'H';
char word[30];
int frequency = -1;
int sample = -1;
char *channels;
channels=malloc(sizeof(7*sizeof(char)));
int bitres = -1;
int secondE = 0;
while (exists == 0) {
scanf("%c", &letter); //this is the problem, possibly scanf
printf("AFTER");
if (letter == EOF) {
// printf(letter);
printf("HEADER NOT DETECTED");
return 0;
}
I've pinpointed the problem using printf. I'm currently piping in another file through command prompt into this program. When I reach scanf it just hangs. If anyone knows the solution I would be very thankful.
On a side note, is using scanf bad practice? It's just as easy to assign stdin to a file pointer (I actually have this commented out) but scanf seemed just as easy.
what do you mean by freezing. i run this code. when your code reach in scanf it wait for your input. you give some input , then see what happen.
scanf is not a bad practice .
channels=(char*)malloc(sizeof(7*sizeof(char)));
int bitres = -1;
int secondE = 0;
while (exists == 0)
{
scanf("%c", &letter); // ok
printf("AFTER");
printf("\n");
printf("%c", letter);
printf("\n");
if (letter == EOF) {
// printf(letter);
printf("HEADER NOT DETECTED"); }
return 0;
}
scanf never return EOF also.
while (exists == 0)
{
scanf("%c", &letter); // ok
printf("AFTER");
printf("\n");
printf("%c", letter);
printf("\n");
if (letter == EOF) {
// printf(letter);
printf("HEADER NOT DETECTED"); }
return 0;
}
So when using this the
if (letter == E0F)
section above is a bit too literal. Why not just use a char to store your desired answer and use the following to create
if(strcmp(letter, *desired char here*) == 0){
just a guess considering the fact it may be client side if your scanf function is freezing only in debug but with the example above it is a bit more user friendly when reading the code and will not have any errors when dealing with other characters and integers later on in your program. Depending on what you want to accomplish with it.