I've been trying to write a program that asks at end of the calculation if we wish to exit it based on input provided. But if I input n, it waits for another input for it to exit the program and after the second input it exits. Is there any way to avoid this? And also the reason why this happens. Here is the complete code.
#include<stdio.h>
int main()
{
float num1, num2;
char op, cont;
while(1)
{
scanf(" %f %c %f",&num1,&op,&num2);
if (op=='+')
printf("%.3f \n",num1+num2);
else if(op=='-')
printf("%.3f \n",num1-num2);
else if(op=='*')
printf("%.3f \n",num1*num2);
else if(op=='/')
{
if(num2==0)
printf("Look where you put your zeroes\n");
else
printf("%.3f\n",num1/num2);
}
else if(op=='%')
printf("%d\n",(int)num1%(int)num2);
else
{
printf("What was the crap you just entered?\n");
}
printf("Continue using calc?[y/n]");
scanf(" %c\n",&cont);
if (cont=='n')
break;
}
return 0;
}
After the following changes I have your program working:
char op, cont='y';
while(cont == 'y')
scanf(" %c", &cont);
Detailed explanation :Simple C scanf does not work?
The problem occured because of the last scanf. For excuting first scanf for num1 op num2 it requires a return (Enter) and after that while executing scanf for char count it takes that last retun key (Enter) as input .. So again it asks for num1 op num2 . this can be stopped by many ways , to stop it via scanf use "scanf(ā
cā
*c,&count)" .%*c will ignore that return key input.
Related
Just started learning C and tried to make a calculator to test myself. I thought it would be a fun challenge to make it so:
the program prints an error message to the user if the input(s) is not a number
the user can input a number again, without shutting down the program
What I've learned in C so far is:
printf, scanf
data types
if statements
loops
functions
My question is, is it possible to accomplish the task with the knowledge mentioned above. If it is, what is that solution? (I've been stuck on this for quite a while now, so I hope me giving up on doing it myself is acceptable). If it's not, what do I need to learn to be able to do it?
Here's my code
#include <stdio.h>
float num1;
float num2;
float answer;
char operation;
int isNumber; //1 means true, 0 means false
char restart;
int main ()
{
printf ("Please enter the first number: ");
isNumber = scanf("%f", &num1);
while (isNumber == 0)
{
printf("Please enter a valid number: ");
isNumber = scanf("%f", &num1);
}
//This just keeps reapeating the printf message.
//Also, I just wrote the code for the first input.
//If it doesn't work for this one, no point in writing it for other inputs.
printf ("Please enter an operation: ");
scanf (" %c", &operation);
printf ("Please enter the second number: ");
scanf ("%f", &num2);
if (operation == '+')
{
answer = num1 + num2;
}
else if (operation == '-')
{
answer = num1 - num2;
}
else if (operation == '*')
{
answer = num1 * num2;
}
else if (operation == '/')
{
while (num2 == 0)
{
printf ("Cannot divide by 0. ");
printf ("Please enter another number\n");
scanf ("%f", &num2);
}
answer = num1 / num2;
}
printf ("\nThe answer is: %f", answer);
printf ("\n\nEnter 1 to do another calculation. Enter anything else to quit: ");
scanf(" %c", &restart);
if(restart == '1')
main();
else
return 0;
}
scanf() only reads input that matches the format specifier (in your case this is %f). Characters that do not match the format specifier causes scanf() to stop scanning and causes scanf() to leave the invalid characters in the stdin buffer.
In your while loop if a invalid character is entered it will get stuck in the stdin buffer. This invalid character will then get read by the next scanf() call in the loop, which will also leave it in the stdin buffer. This will continue, again and again, resulting in an infinite loop.
As you might be able to tell scanf() is a unreliable and quick - yet not very robust way to take input.
To fix it you could use a hacky solution like this:
while ((scanf("%f", &num1)) != 1)
{
printf("Please enter a valid number: ");
int c;
while((c = getchar()) != '\n' && c != EOF);
}
// while loop "eats up" any characters
// that scanf has left in stdin buffer
Instead of scanf() i reccomend you get familiar with a function such as fgets() to take input. Then you can use a function like sscanf() to parse the input to see if it is a float.
As a beginner, while you are learning C, it is fine to use scanf(). But as you delve deeper into C and write more complicated pieces of software you must consider using safer and more robust alternatives to unreliable functions like scanf().
To well handle user input, consider dropping all scanf() calls. To read a line of user input, use fgets().
How to check for non-number inputs
Create a helper function.
Read a line of text into a buffer and parse with sscanf() or strod(). sscanf() is OK and used below. strod() is better, yet some corner cases are beyond what a learner may appreciate.
#define LINE_LENGTH_MAX 400
// Return 1 on success, EOF on end-of-file, 0 on failure
int read_double(double *dest, const char *prompt) {
if (prompt) {
fputs(prompt, stdout);
}
char buffer[LINE_LENGTH_MAX + 1];
if (fgets(buffer, sizeof buffer, stdin) == NULL) {
return EOF;
}
int n = 0;
sscanf(buffer, "%f %n", dest, &n);
if (n == 0) {
// Scanning failed
return 0;
}
if (dest[n]) {
// Yet there was extra junk at the end
return 0;
}
return 1;
}
More advance code would used strtod() and detect lines longer than LINE_LENGTH_MAX.
I have written this simple program, which is supposed to calculate the factorial of a number entered by the user. The program should ask the user to stop or continue the program in order to find the factorial of a new number.
since most of the time user don't pay attention to CapsLock the program should accept Y or y as an answer for yes. But every time I run this program and even though I enter Y/y , it gets terminated !
I googled and found out the problem could be due to new linecharacter getting accepted with my character input so, I modified the scanf code from scanf("%c", &choice); to scanf("%c ", &choice); in order to accommodate the new line character , but my program is still getting terminated after accepting Y/y as input.
Here is the code . Please if possible let me know the best practices and methods to deal with these kinds of issues along with the required correction.
#include<stdio.h>
#include"Disablewarning.h" // header file to disable s_secure warning in visual studio contains #pragma warning (disable : 4996)
void main() {
int factorial=1;//Stores the factorial value
int i; //Counter
char choice;//stores user choice to continue or terminte the program
do {//Makes sure the loop isn't terminated until the user decides
do{
printf("Enter the no whose factorial you want to calculate:\t");
scanf("%d", &i);
} while (i<0);
if (i == 0) //calculates 0!
factorial = 1;
else {//Calculates factorial for No greater than 1;
while (i > 0) {
factorial = factorial*i;
i--;
}
}
printf("\nThe factorialof entered no is :\t%d", factorial);//prints the final result
printf("\nDo you want to continue (Y/N)?");
scanf("%c ", &choice);
} while (choice =="y" || choice =="Y"); // Checks if user wants to continue
}
I'm a beginner in programming and I'm running this code in visual studio 2015.
Just modify your scanf like following:
printf("\nDo you want to continue (Y/N)? ");
scanf(" %c", &choice); //You should add the space before %c, not after
also you should use:
} while (choice == 'y' || choice == 'Y'); // Checks if user wants to continue
NOTE:
Simple quote ' is used for characters and double quote " is used for string
Your second-last line has a string literal "y", which should be a character literal i.e. 'y':
} while (choice =="y" || choice =="Y");
This should be:
} while (choice =='y' || choice =='Y');
Also, your scanf() doesn't consume whitespace. Add a space before %c to make it ignore newlines or other spaces:
scanf(" %c", &choice);
Try doing the following even after the correction there are still some bugs in the code
In your code if you type 'Y' and recalculate a factorial it gives wrong answer as
int factorial is already loaded with the previous value
#include "stdafx.h"
#include <stdio.h>
#include <iostream>
using namespace System;
using namespace std;
int calculateFactorial(int i);
int main()
{
int i;
char choice;
do{
printf("Enter the no whose factorial you want to calculate:\t");
scanf("%d", &i);
printf("\n The factorial of entered no is :\t %d", calculateFactorial(i));
printf("\n Do you want to continue (Y/N)?");
scanf(" %c", &choice);
} while (choice == 'y' || choice == 'Y');
return 0;
}
int calculateFactorial(int i) {
int factorial = 1;
if (i == 0){
factorial = 1;
}else {
while (i > 0){
factorial = factorial*i;
i--;
}
}
return factorial;
}
this is a follow on question from one I asked recently:
C Programming help - providing user with option to exit a program
I now have a new problem. I can get the program to exit if a user enters any letter which is great, but now if a number is entered nothing happens. The while loop doesn't seem to run..
Can you please have a look at my code and see if you can spot what's wrong, thanks. Also, ideally i'd like xterm's window to close if the user wishes to exit. I'd be greatful if anyone could show me how to do this. Anyway here's the code:
#include <stdio.h>
#include <stdlib.h>
int main()
{
float number;
float sum = 0;
printf ("Please enter number or enter any letter to exit:\n");
scanf ("%f", &number);
// if user ENTERS a letter, program will terminate
if(1!=scanf ("%f", &number))
{
getchar();
printf ("Exiting the program...\n");
exit(0);
}
while (1)
{
sum += number;
printf ("Sum: %.2f\n", sum);
printf ("Please enter number or enter any letter to exit:\n");
scanf ("%f", &number);
// if user ENTERS a letter, program will terminate
if(1!=scanf ("%f", &number))
{
getchar();
printf ("Exiting the program...\n");
exit(0);
}
}
return 0;
}
As #BrianCain commented: you are calling scanf a second time in your if statement. If you entered a letter for the first scanf, it forces the second to immediately fail; if you entered a number for the first, then the second is waiting for you to enter another number.
I removed two of your scanf functions and it seems to fix the problem
#include <stdio.h>
#include <stdlib.h>
int main()
{
float number;
float sum = 0;
printf ("Please enter number or enter any letter to exit:\n");
// if user ENTERS a letter, program will terminate
if(1!=scanf ("%f", &number))
{
getchar();
printf ("Exiting the program...\n");
exit(0);
}
while (1)
{
sum += number;
printf ("Sum: %.2f\n", sum);
printf ("Please enter number or enter any letter to exit:\n");
// if user ENTERS a letter, program will terminate
if(1!=scanf ("%f", &number))
{
getchar();
printf ("Exiting the program...\n");
exit(0);
}
}
return 0;
}
The scanf in your if erased the value of the previous one you did.
While the previous two answers are essentially correct, the simple (and clear) version would be:
if(number == 1)
break;
Place this right after your original scanf() and get rid of the other if(..) ..; condition entirely. This will test to see if the number '1' was entered, and if so will break the infinite loop, allowing the program to continue down to the return 0; statement.
It will also deal with what could be confusing style, which is having an exit condition (the final return 0;) that's essentially impossible to get to, or should be.
hello guys I coded something like kfc menu,and I got it to work(finally),but when I input something other than numbers for "menu",eg:the letter "A", I just can't get it to loop again to normal,instead it finishes the program
#include <stdio.h>
#include <stdlib.h>
int main()
{
char counter='y';
float totalprice=0;
while (counter=='Y' || counter=='y')
{
int menu;
float price=0;
printf("\nplease select from menu:");
scanf (" %i", &menu);
switch(menu)
{
case 1: {
printf("\none hotbox1 =RM10.50");
totalprice=totalprice+10.50;
break;
}
case 2: {
printf ("\none hotbox2=RM10.60");
totalprice=totalprice+10.60;
break;
}
case 3:{
printf ("\none hotbox3=RM10.70");
totalprice=totalprice+10.70;
break;
}
default : {
printf ("\nplease enter proper number please:");
scanf("%2f", &menu);
break;
}
}
printf("\n\nadd order?(Y/N):");
scanf (" %c", &counter);
}
printf("\n\nThe total price is: %f", totalprice);
return 0;
}
You should use fgets() (reference here) first and then sscanf() (reference here), checking it's return value to see if it's a number.
char inputBuffer[MAX_BUFFER];
do
{
fgets(inputBuffer, MAX_BUFFER, stdin);
}
while(sscanf(inputBuffer, "%d", &menu) != 1)
You scanf with %f in the default case, I am fairly certain that is for floats. Use %d.
Remove scanf("%2f", &menu);
Switch in C does not support char in switch-case. Before you start switch-case validate the user input. If it is a number go into switch case otherwise display a user message to enter only numeric value
I recommend that you debug this by printing out the value of "counter" at various points in the loop (i.e. after you read it in, at the bottom of the loop, etc.). This will give you visibility into what your code is doing.
You can try something like this
#include <stdio.h>
int main()
{
char counter;
float totalprice=0;
int menu=0;
do
{
printf("\n1. one hotbox1=RM10.50");
printf("\n2. one hotbox2=RM10.60");
printf("\n3. one hotbox3=RM10.70");
printf("\nplease select from menu:");
scanf ("%d", &menu);
switch(menu)
{
case 1:
printf("\none hotbox1 =RM10.50");
totalprice=totalprice+10.50;
break;
case 2:
printf ("\none hotbox2=RM10.60");
totalprice=totalprice+10.60;
break;
case 3:
printf ("\none hotbox3=RM10.70");
totalprice=totalprice+10.70;
break;
default :
printf ("\nplease enter proper number please:");
scanf("%d", &menu);
}
printf("\n\nadd more order?(Y/N):");
fflush(stdin); //to empty the input stream.
scanf("%c",&counter);
}while(tolower(counter) != 'n'); //tolower returns the lowercase character.
printf("\n\nThe total price is: %.2f", totalprice);
return 0;
}
When scanf("%i", &menu) tries to read an integer from the input, it finds A, which it cannot interpret as a number, so it does not read it(*). Then the next scanf continues reading the input from when the other left off and happily reads the letter 'A'. Since you loop as long as the read letter is either 'y' or 'Y' (which A is neither), it exits the loop.
(*) read up on the documentation of scanf to see how to tell if it encountered an error.
Note: scanf("%i", &menu) should be scanf("%d", &menu) as%d` is the formatting symbol for integers.
One solution would be to change the loop condition to:
while (counter!='N' && counter!='n')
{
...
}
This way you end the loop only if an explicit 'N' or 'n' is inputted.
Note: it won't help if you accidentally type 'n' for the menu item, so see the comment about the error handling above.
I can't see why does the While loop just speed away and skipping the scanf for the char?
It would not even ask for my input and just loop like there's no tomorrow.
#include <stdio.h>
int main()
{
int number;
int multiply, ans;
char choice;
printf("-------------------------------------");
printf("\n MULTIPLICATION TABLE ");
printf("\n-------------------------------------");
do
{
printf("\nEnter an integer number:");
scanf("%d", &number);
printf("\nMultiplication of %d is :-\n", number);
printf("\n");
for(multiply=1; multiply<11; multiply++){
ans = number * multiply;
printf(" %d", ans);
}
printf("\n");
printf("\nWould you like to continue? [Y] for Yes,[N] for no : ");
scanf("%c", &choice);
printf("\n");
}
while(choice='Y');
printf("Thank You");
return 0;
}
scanf() doesn't do what you think it does (newline characters, buffering, etc.). It's preferred to use fgetc():
choice = fgetc(stdin);
For the same reason, you need to get rid of the trailing newline that
scanf("%d", &number");
leaves in the standard input buffer. To fix this, insert
fgetc(stdin);
after that particular call to scanf().
Also, C is not Pascal. The equality comparison operator - and the condition - you're looking for is
while (choice == 'Y')
the single equation mark denotes an assignment.
I think you need to use == operator for the comparison in while condition check as:
while(choice=='Y');
Currently you are using = operator, which is assigning Y to choice variable.
It has been a long time since I programmed in that language, but at a glance, you have:
while(choice='Y');
instead of:
while(choice=='Y');
== compares, = sets equal to. So the while loop is actually not checking the condition you're trying to set.