How to enter a letter to quit a program in C - c

I am new to C programming. I have been writing this code to add numbers and I just need help with this one thing. When I type the letter 'q', the program should quit and give me the sum. How am I supposed to do that? It is currently the number 0 to close the program.
#include <stdio.h>
int main()
{
printf("Sum Calculator\n");
printf("==============\n");
printf("Enter the numbers you would like to calculate the sum of.\n");
printf("When done, type '0' to output the results and quit.\n");
float sum,num;
do
{
printf("Enter a number:");
scanf("%f",&num);
sum+=num;
}
while (num!=0);
printf("The sum of the numbers is %.6f\n",sum);
return 0;
}

One approach would be to change your scanf line to:
if ( 1 != scanf("%f",&num) )
break;
This will exit the loop if they enter anything which is not recognizable as a number.
Whether or not you take this approach, it is still a good idea to check the return value of scanf and take appropriate action if failed. As you have it now, if they enter some text instead of a number then your program goes into an infinite loop since the scanf continually fails without consuming input.

It's actually not as straightforward as you'd think it would be. One approach is to check the value returned by scanf, which returns the number of arguments correctly read, and if the number wasn't successfully read, try another scanf to look for the quit character:
bool quit = false;
do
{
printf("Enter a number:");
int numArgsRead = scanf("%f",&num);
if(numArgsRead == 1)
{
sum+=num;
}
else // scan for number failed
{
char c;
scanf("%c",&c);
if(c == 'q') quit = true;
}
}
while (!quit);

If you want your program to ignore other inputs (like another letter wouldn't quit) it gets more complicated.
The first solution would be to read the input as a character string, compare it to your character and then convert it to a number later. However, it has many issues such as buffer overflows and the like. So I'm not recommending it.
There is however a better solution for this:
char quit;
do
{
printf("Enter a number:");
quit=getchar();
ungetc(quit, stdin);
if(scanf("%f", &num))
sum+=num;
}
while (quit!='q')
ungetc pushes back the character on the input so it allows you to "peek" at the console input and check for a specific value.
You can replace it with a different character but in this case it is probably the easiest solution that fits exactly what you asked. It won't try to add numbers when the input is incorrect and will quit only with q.

#Shura
scan the user input as a string.
check string[0] for the exit condition. q in your case
If exit condition is met, break
If exit condition is not met, use atof() to convert the string to double
atof() reference http://www.cplusplus.com/reference/cstdlib/atof/

Related

isdigit() and system("cls") produce infinite loop

I was at first having trouble with a scanf() function being skipped, but I fixed that by adding in a space before %c in the scanf() function.
When trying to ask for input from the user as to whether the screen should be cleared, the scanf(" %c", cClear); conversion specifier gives an infinite loop, it is expecting a character, but responds to input as if not a character.
I believe it may have something to do with my input buffer.
I tried to use fflush(stdin) to no avail, I also used printf("%d", (int) cClear); to see the output, which was zero.
One other problem I have is trying to check user input for a digit.
I use:
if (isdigit(iSelection) == 0) {
printf("\nPlease select a valid numerical value.\n");
continue;
to check user input and restart the while loop, but anytime a character is entered and not an integer, I get an infinite loop.
My goal is to give the user the option to clear the screen after each calculation, and to also check input for being a digit.
Any help is appreciated.
//excluding code prior to main() and function definitions
int main(void) {
int iSelection = -1;
double foperand1 = 0, foperand2 = 0;
int ioperand1 = 0, ioperand2 = 0;
char cClear = '\0';
while (iSelection) {
printf("\n\nTHE CALCULATOR\n");
printf("\nCalculator menu:\n");
printf("\n1\tAddition");
printf("\n2\tSubtraction");
printf("\n3\tMultiplication");
printf("\n4\tDivision");
printf("\n5\tModulus (Integers only)");
printf("\n6\tTest if Prime (Integers only)");
printf("\n7\tFactorial (Integers only)");
printf("\n8\tPower");
printf("\n9\tSquare Root");
printf("\n0\tExit\n");
printf("\nPlease enter your selection: ");
scanf("%d", &iSelection);
//here we check for if input was a digit
if (isdigit(iSelection) == 0) {
printf("\nPlease select a valid numerical value.\n");
continue;
switch(iSelection) {
case 0:
break;
case 1:
printf("\nEnter the two numbers to add seperated by a space: ");
scanf("%lf %lf", &foperand1, &foperand2);
printf("\n%.5lf + %.5lf = %.5lf\n", foperand1, foperand2, addNumbers(foperand1, foperand2));
break;
}
//here we ask the user if they want to clear the screen
fflush(stdin)
if (iSelection != 0) {
printf("\nDo you want to clear the screen? ('y' or 'n'): ");
scanf("%c", cClear);
//printf("%d", (int) cClear); //used this to help debug
//scanf("%d", iSelection);
if (cClear == 'y')
system("cls");
}
}
printf("\nExiting\n");
return 0;
}
one error I get is "system" is declared implicitely. Could it possibly be the windows operating system not recognizing the pre defined function call?
Thanks to the people who commented to help me figure this out.
I had forgotten to add the (&) to the scanf() function call for the system"cls" function call, as well as didn't include the correct library (stdlib.h).
I was also able to make the program stop skipping the scanf() function by adding a space to the " %c" conversion specifier.
scanf Getting Skipped
I was able to make the isdigit() function work by changing the variable 'iSelection' to a character, but then I also had to change my case values to characters, not integers.

While using scanf("%i",var) if the user enters a letter or just presses enter i get a problem

I want for my program to just ask again if the user entered a letter or just pressed enter.
I know that if the input is not a number scanf() will return 0, so i have been doing this:
int variable;
printf("Please write an integer and then press enter: \n");
if (scanf("%i",&variable)!= 1) { /* ERROR CODE */; return 1;}
return 0;
But i dont want for my program just to stop if the input is not correct. So i tried this:
int variable;
do
{
printf("Please write an integer and then press enter: \n");
} while (scanf("%i",&variable) != 1);
But the program will just start printing "Please write an integer and then press enter:" without stoping. Is there a way of doing this?
edit: Forgot the &
edit2: Thanks to everybody.
edit3: I have been looking into the functions. Will this code be correct?
char variable[10]; int var;
do
{
printf("Please write an integer: ");
fgets(variable,sizeof(variable),stdint);
} while( sscanf(variable,"%i",&var) != 1 );
I have tried it and it works but i post it here because i know im probably missing something.
int variable;
do {
printf("Please write an integer and then press enter: \n");
} while (scanf("%i", &variable) != 1 && scanf("%*[^\n]") == 0);
The second scanf discards characters till the '\n' character. The '\n' character remains, though it will be skipped by the first scanf on the next iteration of the loop.
The code has some defects but it will work in most cases. One defect is that, if scanf returns EOF without reading a character then the loop will exit but the value of variable will be indeterminate, which can cause undefined behaviour when used. This one is not difficult to cure. Another one is that, the behaviour is undefined if the user enter a number outside of range for int. So a way better approach, is to use fgets and strtol library functions.

do-while loop "enter more (y/n)" - character issue

So I'm working on basic C skills, and I want to design a code which enters as many numbers as the user wants. Then, it should display the count of positive,negative & zero integers entered.
I've searched Google & StackOverflow. The code seems fine according to those programs.
It compiles & runs. But whenever I input anything after the prompt "enter more? y/n", it returns to the code..
Please have a look at the code below:
#include<stdio.h>
int main()
{
int no,count_neg=0,count_pos=0,count_zero=0;
char ch='y';
clrscr();
do
{
puts("Enter number");
scanf("%d",&no);
if (no>0)
count_pos++;
else if (no<0)
count_neg++;
else
count_zero++;
puts("want more? - y/n ");
scanf("%c",&ch);
}
while (ch=='y');
if (ch=='n')
{
printf("No of positives = %d",count_pos);
printf("No of negatives = %d",count_neg);
printf("No of zeros = %d",count_zero);
}
getch();
return 0;
}
The problem is with "scanf("%c", &ch);"
What happens actually is :
Suppose you enter 'y' as a choice and hit 'enter'(return), the return is a character and
its character value is 10(since its a new line character), thus the scanf takes the 'return'
as its input and continues.
Solution :
1. use getchar() before scanf()
// your code
getchar();
scanf();
//your code
getchar() takes the return value as its input, thus you are left with your actual value.
add '\n' to scnaf()
// code
scanf("\n%c", &ch);
//code
when scanf() encounters the '\n' character it skips it (google about scanf, to know how
and why ), thus stores the intended value inside 'ch'.
A "better" form for:
int main()
is:
int main(void)
clrscr is not standard C.
You ought to check the return-value of any function which might indicate "interesting status," such as a failure condition, and from which you can gracefully deal with the situation. In this case, scanf is such a function.
I believe that your first do ... while condition will become false because it will pick up the newline character following your first scanf call. You might want to read about getchar or getc, instead of using scanf for the task of checking whether or not to run the loop again. You can "eat" unwanted characters, including a newline.
Here, I have corrected the problem. The problem was this that the "enter" you press after each number is a character and is takenup by the scanf() as it is there to scan some characters. So I have added a getchar(); before the scanf();so the "enter" is taken up by getchar(); and scanf() is now free to take your input.
#include<stdio.h>
int main()
{
int no,count_neg=0,count_pos=0,count_zero=0;
char ch='y';
clrscr();
do
{
puts("Enter number");
scanf("%d",&no);
if(no>0)
count_pos++;
else if(no<0)
count_neg++;
else
count_zero++;
puts("want more? - y/n ");
getchar();//<---- add this here
scanf("%c",&ch);
}
while(ch=='y');
if(ch=='n')
{
printf("No of positives = %d",count_pos);
printf("No of negatives = %d",count_neg);
printf("No of zeros = %d",count_zero);
}
getch();
return 0;
}
To fix the input is to use a C String like this scanf("%s",...);
This might break if you input more than one character because scanf will keep reading until the user hits enter, and your ch variable is only enough space for one character.
I run your code in Online compiler. I am not sure about other compiler.
I slightly changed your code. i.e., first i read char then int. If i do not change the order, char variable holds int variable value. This is the reason ( ch variable holds values of no variable).
#include<stdio.h>
int main()
{
int no,count_neg=0,count_pos=0,count_zero=0;
char ch='y';
do
{
puts("Enter number");
scanf("%c",&ch);
scanf("%d",&no);
if(no>0)
count_pos++;
else if(no<0)
count_neg++;
else
count_zero++;
puts("want more? - y/n ");
}
while(ch=='y');
if(ch=='n')
{
printf("No of positives = %d",count_pos);
printf("No of negatives = %d",count_neg);
printf("No of zeros = %d",count_zero);
}
return 0;
}
EDIT:
whenever integer and char are read through keyboard. it stores int value and enter key value. so this is the reason.
You have to add
scanf("%d",&no);
you code
......
.....
fflush(stdin);
scanf("%c",&ch);
use:
ch = getche();
instead of:
scanf("%c", &ch);

do while loop for Yes/No user prompt

My program which finds prime factors is all set...the only thing left that I need to do is this type of output:
Do you want to try another number? Say Y(es) or N(o): y
//asks for another number (goes through the program again)
Do you want to try another number? Say Y(es) or N(o): n
//Thank you for using my program. Good Bye!
I have my attempt at this below...When I type n it does the correct output. But if I type 'y' it just says the same thing n does....How can I loop the entire program without putting the code for the program inside this while loop I have? So when I press y it goes through the program again?
int main() {
unsigned num;
char response;
do{
printf("Please enter a positive integer greater than 1 and less than 2000: ");
scanf("%d", &num);
if (num > 1 && num < 2000){
printf("The distinctive prime facters are given below: \n");
printDistinctPrimeFactors(num);
printf("All of the prime factors are given below: \n");
printPrimeFactors(num);
}
else{
printf("Sorry that number does not fall within the given range. \n");
}
printf("Do you want to try another number? Say Y(es) or N(o): \n");
response = getchar();
getchar();
}
while(response == 'Y' || response == 'y');
printf("Thank you for using my program. Goodbye!");
return 0;
} /* main() */
The problem is probably, that you're getting something that isn't y from getchar and the loop exits, as the condition is not matched.
getchar() may use a buffer, so when you type 'y' and hit enter, you will get char 121 (y) and 10 (enter).
Try the following progam and see what output you get:
#include <stdio.h>
int main(void) {
char c = 0;
while((c=getchar())) {
printf("%d\n", c);
}
return 0;
}
You will see something like this:
$ ./getchar
f<hit enter>
102
10
What you can see is that the keyboard input is buffered and with the next run of getchar() you get the buffered newline.
EDIT: My description is only partially correct in terms of your problem. You use scanf to read the number you're testing against. So you do: number, enter, y, enter.
scanf reads the number, leaves the newline from your enter in the buffer, the response = getchar(); reads the newline and stores the newline in response, the next call to getchar() (to strip the newline I described above) gets the 'y' and your loop exits.
You can fix this by having scanf read the newline, so it doesn't linger in the buffer: scanf("%d\n", &number);.
When reading input using scanf (when you enter your number above), the input is read after the return key is pressed but the newline generated by the return key is not consumed by scanf.
That means your first call to getchar() will return the newline (still sitting in the buffer), which is not a 'Y'.
If you reverse your two calls to getchar() - where the second one is the one you assign to your variable, your program will work.
printf("Do you want to try another number? Say Y(es) or N(o): \n");
getchar(); // the newline not consumed by the scanf way above
response = getchar();
just put getchar() after scanf statement of yours that will eat the unnecessary '\n' from buffer...
As others have stated, there is a single '\n' character in the input stream left over from your earlier call to scanf().
Fortunately, the standard library function fpurge(FILE *stream) erases any input or output buffered in the given stream. When placed anywhere between your calls to scanf() and getchar(), the following will rid stdin of anything left in the buffer:
fpurge(stdin);

getchar not working in switch case (c)

Using a very simple calculator program that prompts a user for an operation to perform, followed by a prompt for two integers on which to perform this operation. The program is supposed to loop after these operations, except in the case where the user enters the character 'q', at which point the program is supposed to quit.
#include <stdio.h>
int main (void)
{
char c;
int number[2], num1, num2, result;
double num1d, num2d, resultd;
int done=1;
while(done)
{
printf("\t What sort of operation would you like to perform? \n \t Type + - * / accordingly. \n");
c = getchar();
printf("\tplease enter a number \n");
scanf("%d",&number[0]);
printf("\tplease enter another number \n");
scanf("%d",&number[1]);
num1 = number[0];
num2 = number[1];
switch(c)
{
case('-'):
result = num1-num2;
printf("\nThe first number you entered subtracted by the second number is %d.\n", result);
break;
case('+'):
result = num1+num2;
printf("The first number you entered added to the second number is %d.\n", result);
break;
case('*'):
result = num1*num2;
printf("The first number you entered multiplied with the second number is %d.\n", result);
break;
case('/'):
num1d = (double) num1;
num2d = (double) num2;
resultd = num1d/num2d;
printf("The first number you entered divided by the second number is %g.\n", resultd);;
break;
case('q'):
printf(" Now Exiting...\n");
done=0;
break;
default:
puts("Invalid key pressed. Press q to exit");
break;
}
}
return 0;
}
Works correctly for a single calculation, but subsequently performs oddly; in particular it prints
printf("\t What sort of operation would you like to perform? \n \t Type + - * / accordingly. \n");
printf("\tplease enter a number \n");
altogether.
The standard method of clearing the input buffer while (getchar() != '\n'); doesn't fix this. One out of two times that this text displays incorrectly the user can still use the program as if the instructions were displaying as they should (so the user can type an operation such as +, carriage return, and then some integer and a carriage return, and the program will perform correctly from that point on) Every other time however the program will put "Invalid key pressed. Press q to exit" regardless of input.
What everyone else here is saying is true, getchar() returns an int but that's not your problem.
The problem is that getchar() leaves a newline character after you use it. If you're going to use getchar() you must always consume the newline char afterwards. This simple fix:
printf("\t What sort of operation would you like to perform? \n \t Type + - * / accordingly. \n");
c = getchar();
getchar(); //<-- here we do an extra getchar for the \n
printf("\tplease enter a number \n");
scanf("%d",&number[0]);
printf("\tplease enter another number \n");
scanf("%d",&number[1]);
and that will eliminate the problem. Every time you type <somechar><enter> it's really putting two characters on the buffer, for example if I hit + and enter I'm getting:
'+''\n' // [+][\n]
getchar() will only get the first of these, then when getchar() is called again it won't wait for your input it will just take that '\n' and move on to the scanf()
You shouldn't mix character-by-character with more high-level input functions such as scanf(). It's better to use scanf() to input the command character too, but of course then you will have to press enter after the command. I believe this it the root cause of your problems.
As an aside, note that getchar(), despite it's name, returns int, not char. This is because it can return EOF which is a special constant whose value is different from that of all characters.
Further, you should always check the return value of I/O functions like scanf(), they can fail if the input doesn't match the pattern string.
As a debugging hint, you can of course print the value of c before interpreting it, so you can easier see and understand the flow of the program.
I'm guessing it works the first time, but not the next time. This is because the scanf calls leaves the newline in the input buffer so the next time getchar is called in the loop it will return the newline character. Add a space after the format in the scanf calls
scanf("%d ",&number[0]);
and it will discard remaining whitespace from the buffer.
Use a debugger to step through the code and check the variables to verify.
Your getchar should return int. The reason is as below
getchar reads characters from the program's standard input
and returns an int value suitable for storing into a char.
The int value is for one reason only: not only does getchar
return all possible character values, but it also returns an
extra value to indicate that end-of-input has been seen.
The range of a char might not be enough to hold this extra value,
so the int has to be used.
So basically you need to change char c to int c in your code

Resources