How to make getchar() read a negative number? - c

I am writing a program that can calculate the areas of a square, cube, and circle. The program needs to present an error message and allow the user to enter a new choice if they enter something not included in the menu. My problem is that if they type anything includes my menu options then the program still executes. (i.e. -1, 23, 344) I was wondering how to get it to ignore anything after the first character or to read the whole string. Or if there is something better than getchar(). I'm open to any solutions! Thank you!
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int choice;
int lengthsq;
int areasq;
int lengthcube;
int areacube;
int radius;
double circlearea;
printf("Area Calculation\n");
printf("(1) Square\n");
printf("(2) Cube\n");
printf("(3) Circle\n");
fputs("Please make a selction: ", stdout);
while((choice = getchar()) != '\n')
switch (choice) {
case '1':
printf("\nPlease enter the length: ");
scanf("%d", &lengthsq);
while(lengthsq <= 0){
printf("Error! Please enter a positive number: ");
scanf("%d", &lengthsq);
}
areasq = lengthsq * lengthsq;
printf("The area of the square is %d.", areasq);
return 0;
case '2':
printf("\nPlease enter the length: ");
scanf("%d", &lengthcube);
while (lengthcube <= 0) {
printf("Error! Please enter a positive number: ");
scanf("%d", &lengthcube);
}
areacube = 6 * lengthcube * lengthcube;
printf("The surface area of the cube is %d.\n", areacube);
return 0;
case '3':
printf("\nPlease enter the radius: ");
scanf("%d", &radius);
while(radius <= 0){
printf("Error! Pleae enter a postive number: ");
scanf("%d", &radius);
}
circlearea = 3.14159 * radius * radius;
printf("The area of the circle is %.2f.\n", circlearea);
return 0;
case '\n':
case '\t':
case ' ':
break;
default:
printf("\nInvalid choice entered.\n");
fputs("Enter a new choice: ", stdout);
break;
}
}

You could add another switch case for the dash, which would toggle some kind of negative flag and then read a number as you're already doing. If you do not like introducing such a flag, then the best option would be using fgets, which returns the entire input line. But that has the downside that you need to parse the input. I.e. do some string manipulation, which may be slightly more complex than a simple flag parameter.
On the other hand, from the code you attached, I deduct that the only valid input consists of mere numbers (integers). You could just read an integer then with scanf.

Related

getchar() not waiting for input and jumping directly to next line

getchar() not waiting for input and jumping directly to next line. There is some mismatch between scanf and getchar I think but not able to make out what is it exactly.
#include<stdio.h>
#include<ctype.h>
int main()
{
char ch;
int n1,n2;
printf("Enter the operation of your choice\n");
printf("a. add\ts. subtact\nm. multiply\td. divide\nq. quit\n");
while((ch=getchar())!='q')
{
printf("\nEnter 1st number:\n");
if(scanf("%d",&n1)!=1)
{
printf("Please enter an integer value.\n");
continue;
}
printf("Enter 2nd number:\n");
if(scanf("%d",&n2)!=1)
{
printf("Please enter an integer value.\n");
continue;
}
switch(ch)
{
case 'a':
{ printf(" %d + %d = %d\n",n1,n2,n1+n2);
break;
}
case 's':
{
printf(" %d - %d = %d\n",n1,n2,n1-n2);
break;
}
case 'm':
{
printf(" %d * %d = %d\n",n1,n2,n1*n2);
break;
}
case 'd':
{
if(n2!=0)
{
printf(" %d / %d = %f\n",n1,n2,(float)n1/n2);
break;
}
else
{
printf("Enter a non-zero number for n2\n");
continue;
}
break;
}
}
printf("Enter the operation of your choice\n");
printf("a. add\ts. subtact\nm. multiply\td. divide\nq. quit\n");
}
printf("Bye.");
}
OUTPUT:
Enter the operation of your choice
a. add s. subtact
m. multiply d. divide
q. quit
a
Enter 1st number:
50
Enter 2nd number:
25
50 + 25 = 75
Enter the operation of your choice
a. add s. subtact
m. multiply d. divide
q. quit
Enter 1st number:
your getchar reads the newline and other spaces you enter when you give the value read by the scanf, you need to bypass these spaces
just replace
while((ch=getchar())!='q')
by
while ((scanf(" %c", &ch) == 1) && (ch != 'q'))
notice the space before '%', this is thank to it the spaces including newline are bypassed

I need my program to tell the user "invalid entry..." if they dont input a correct variable type

The issue im having is when the user is prompted to enter a value if an invalid option is entered that is not of the type im scanning for i need the program to display a message "invalid entry" and break.
if (UserInputTri == 'A')
{
system("cls");
TriPermTotal = 0;
printf("\nYou chose to calculate perimeter.\n\nPlease enter a value for side number 1: ");
scanf("%f", &TriPerm1);
printf("Please enter a value for side number 2: ");
scanf("%f", &TriPerm2);
printf("Please enter a value for side number 3: ");
scanf("%f", &TriPerm3);
TriPermTotal = TriPerm1 + TriPerm1 + TriPerm3;
printf("\nThe total perimeter of the triangle is: %0.0f\n\n", TriPermTotal);
system("pause");
system("cls");
break;
else
{
printf("\nNot a valid option, try again!\n\n");
system("pause");
system("cls");
break;
}
If I type in a word instead of a number when the user is asked for side 1 it will loop forever.

How can i make the user choose the unit

I have a converter, but it converts all the units that are in the program.how can i make that the user who opens the project to choose what type of unit to convert?
#include<stdio.h>
#include<conio.h>
int main()
{
float m, f, l, g, cm, inch;
printf("Type meter : ");
scanf("%f",&m);
f = 3.2808399 * m;
printf("feets: %f",f);
printf("\nType gallons : ");
scanf("%f",&g);
l = 3.78541178 * g;
printf("litres: %f",l);
printf("\ninches : ");
scanf("%f", &inch);
cm = 2.54 * inch;
printf("cm: %f", cm);
return 0;
}
This code below is definitely not the best one in terms of complexity, portability, optimisation (Memory/Time) and many other aspects of programming, but it should get you going.
I have added comments to explain the code. Almost all of the code with all those printfs is self-explanatory.
#include<stdio.h>
int main(void)
{
// We need just 3 variables
// This one is for getting the user option
int choice = 0;
// We need these to float variables for user input and an output
float Input = 0.0, Output = 0.0;
// Following code till `while(1)` is optional.
printf("\nThis is a converter with a fixed set of functions.");
printf("\nNote: This converter does support floating point inputs.");
printf("\nNote: Floating point inputs and outputs are truncated to 2 digits after decimal place.");
printf("\nNote: Press any key to acknowledge!");
getchar();
// To get user input multiple times, you'll need to loop
while(1)
{
printf("\n\nFollowing functions are supported, enter a suitable choice form the list below.");
printf("\nPress `1` for Converting Metres to Feet.");
printf("\nPress `2` for Converting Gallons to Litres.");
printf("\nPress `3` for Converting Inches to Centimetres.");
printf("\nPress `0` for Exiting the program.");
printf("\nEnter your Option : ");
scanf("%d", &choice);
// Lets implement a switch-case statement to get the job done
switch(choice)
{
case 1:
printf("Enter input value (in Metres) : ");
scanf("%f",&Input);
Output = 3.2808399 * Input;
printf("%0.2f Metres is equal to %0.2f Feets", Input, Output);
break;
case 2:
printf("Enter input value (in Gallons) : ");
scanf("%f",&Input);
Output = 3.78541178 * Input;
printf("%0.2f Gallons is equal to %0.2f Litres", Input, Output);
break;
case 3:
printf("Enter input value (in Inches) : ");
scanf("%f",&Input);
Output = 2.54 * Input;
printf("%0.2f Inches is equal to %0.2f Centimetres", Input, Output);
break;
case 0:
printf("Thank you. The program will exit now!\n\n");
return 0;
break;
// This default case should take care of the invalid set of choices entered by user
default:
printf("Option you entered is either invalid or is not supported as of now!");
}
}
return 0;
}
Another way to implement this could be using an if-else if-else ladder.
So you can remove swtich-case statements from the code below and replace it with the following:
if(choice == 0)
{
printf("Thank you. The program will exit now!\n\n");
return 0;
}
else if(choice == 1)
{
printf("Enter input value (in Metres) : ");
scanf("%f",&Input);
Output = 3.2808399 * Input;
printf("%0.2f Metres is equal to %0.2f Feets", Input, Output);
}
else if(choice == 2)
{
printf("Enter input value (in Gallons) : ");
scanf("%f",&Input);
Output = 3.78541178 * Input;
printf("%0.2f Gallons is equal to %0.2f Litres", Input, Output);
}
else if(choice == 3)
{
printf("Enter input value (in Inches) : ");
scanf("%f",&Input);
Output = 2.54 * Input;
printf("%0.2f Inches is equal to %0.2f Centimetres", Input, Output);
}
else
{
// This should take care of the invalid set of choices entered by user
printf("Option you entered is either invalid or is not supported as of now!");
}
char unit;
printf("Which unit do you want to convert (input:m,g,i): ");
scanf("%c",&unit);
if(unit == 'm') ...
else if( if(unit == 'g'))....
else if( if(unit == 'i'))....
else printf("wrong input ! \n");

How to make this program ask for input again if invalid input is entered (in C programming)? [duplicate]

This question already has answers here:
Why is scanf() causing infinite loop in this code?
(16 answers)
Closed 5 years ago.
There are two different spots where the check happens.
That is, where you enter a, s, m, d, or q and when you enter the first and second number.
At any of the checks, if the check is false, it should ask you to re-enter your input.
I'm guessing this can be done by putting a scanf statement for the numbers part inside a while loop check, but when I enter an invalid value (non-number) the loop runs infinitely.
So I must be doing something wrong. I have made the a, s, m, d, and q part work for the most part.
But the second part never seems to work. For this, I left my failed attempts at the while loops out, and instead in //comments.
Any help would be greatly appreciated!
Here is my code so far:
#include <stdio.h>
#include <ctype.h>
int main(void)
{
char ch;
float num1,num2,answer;
printf("Enter the operation of your choice:\n");
printf("a. add s. subtract\n");
printf("m. multiply q. divide\n");
printf("q. quit\n");
while ((ch = getchar())!='q')
{
printf("Enter the operation of your choice:\n");
printf("a. add s. subtract\n");
printf("m. multiply q. divide\n");
printf("q. quit\n");
ch=tolower(ch);
if (ch=='\n')
continue;
else
{
switch(ch)
{
case 'a':
//The code below is what I have tried to make work.
//This code would also be copy pasted to the other cases,
//of course with the correct operations respectively being used.
//
//printf("Enter first number: ")
//while(scanf("%f",&num1)==0)
//{
// printf("Invalid input. Please enter a number.");
// scanf("%f",&num1);
//}
//printf("Enter second number: ")
//while(scanf("%f",&num2)==0)
//{
// printf("Invalid input. Please enter a number.");
// scanf("%f",&num2);
//}
//answer = num1 + num2;
//printf("%f + %f = %f\n",num1,num2,answer);
//break;
//
//I have also tried to make this work using do-while loops
printf("Enter first number: ");
scanf("%f",&num1);
printf("Enter second number: ");
scanf("%f",&num2);
answer = num1 + num2;
printf("%f + %f = %f\n",num1,num2,answer);
break;
case 's':
printf("Enter first number: ");
scanf("%f",&num1);
printf("Enter second number: ");
scanf("%f",&num2);
answer = num1 - num2;
printf("%f - %f = %f\n",num1,num2,answer);
break;
case 'm':
printf("Enter first number: ");
scanf("%f",&num1);
printf("Enter second number: ");
scanf("%f",&num2);
answer = num1 * num2;
printf("%f * %f = %f\n",num1,num2,answer);
break;
case 'd':
printf("Enter first number: ");
scanf("%f",&num1);
printf("Enter second number: ");
scanf("%f",&num2);
answer = num1 / num2;
printf("%f / %f = %f\n",num1,num2,answer);
break;
default:
printf("That is not a valid operation.\n");
break;
}
}
}
return 0;
}
Again, thanks for any help!
Ya'll would be a life saver!
Cheers!
-Will S.
EDIT: I got my code to work! Here is the final code...
#include <stdio.h>
#include <ctype.h>
int main(void)
{
char ch;
float num1,num2,answer;
printf("Enter the operation of your choice:\n");
printf("a. add s. subtract\n");
printf("m. multiply q. divide\n");
printf("q. quit\n");
while ((ch = getchar())!='q')
{
ch=tolower(ch);
//Ignore whitespace
if (ch=='\n')
continue;
else
{
switch(ch)
{
//Addition part
case 'a':
//First number
printf("Enter first number: ");
//Check to see if input is a number
while (scanf("%f",&num1)==0)
{
printf("Invalid input. Please enter a number, such as 2.5, -1.78E8, or 3: ");
scanf("%*s");
}
//Second number
printf("Enter second number: ");
while (scanf("%f",&num2)==0)
{
printf("Invalid input. Please enter a number, such as 2.5, -1.78E8, or 3: ");
scanf("%*s");
}
//Do math for respective operation
answer = num1 + num2;
//Print out result
printf("%.3f + %.3f = %.3f\n", num1,num2,answer);
break;
//Subtraction part
case 's':
printf("Enter first number: ");
while (scanf("%f",&num1)==0)
{
printf("Invalid input. Please enter a number, such as 2.5, -1.78E8, or 3: ");
scanf("%*s");
}
printf("Enter second number: ");
while (scanf("%f",&num2)==0)
{
printf("Invalid input. Please enter a number, such as 2.5, -1.78E8, or 3: ");
scanf("%*s");
}
answer = num1 - num2;
printf("%.3f - %.3f = %.3f\n", num1,num2,answer);
break;
//Multiplication part
case 'm':
printf("Enter first number: ");
while (scanf("%f",&num1)==0)
{
printf("Invalid input. Please enter a number, such as 2.5, -1.78E8, or 3: ");
scanf("%*s");
}
printf("Enter second number: ");
while (scanf("%f",&num2)==0)
{
printf("Invalid input. Please enter a number, such as 2.5, -1.78E8, or 3: ");
scanf("%*s");
}
answer = num1 * num2;
printf("%.3f * %.3f = %.3f\n", num1,num2,answer);
break;
//Division part
case 'd':
printf("Enter first number: ");
while (scanf("%f",&num1)==0)
{
printf("Invalid input. Please enter a number, such as 2.5, -1.78E8, or 3: ");
scanf("%*s");
}
printf("Enter second number: ");
while (scanf("%f",&num2)==0)
{
printf("Invalid input. Please enter a number, such as 2.5, -1.78E8, or 3: ");
scanf("%*s");
}
//Check for if number is a zero
while (num2==0)
{
printf("Please enter a non-zero number, such as 2.5, -1.78E8, or 3: ");
while (scanf("%f",&num2)==0)
{
printf("Invalid input. Please enter a number, such as 2.5, -1.78E8, or 3: ");
scanf("%*s");
}
}
answer = num1 / num2;
printf("%.3f / %.3f = %.3f\n", num1,num2,answer);
break;
//For if a non-valid operation is entered
default:
printf("That is not a valid operation.\n");
break;
}
}
printf("Enter the operation of your choice:\n");
printf("a. add s. subtract\n");
printf("m. multiply q. divide\n");
printf("q. quit\n");
}
printf("Bye.\n");
return 0;
}
Looking back at it, I probably could do without the if/else statement.
There are multiple problems with your code. First of all in this loop
You are taking input two times on failure
while(scanf("%f",&num1)==0) //Taking Input Here Once
{
printf("Invalid input. Please enter a number.");
scanf("%f",&num1); //Again Taking input.
}
Instead what you wanted was to check the return value of the scanf() and if it was 0 you would execute the loop again, so this would be the way to do that:
int l = 0;
while(l==0){ //Checking l, if it is zero or not, if zero running loop again.
printf("Invalid input. Please enter a number.");
l = scanf("%f",&num1); //Storing Return Value of scanf in l
}
When the program will encounter any line with scanf("%f" , &num1) or scanf("%f" , &num2), it will skip all the white spaces and wait for next input. In the case where the input does not match the format specification, then the input isn't consumed and remains in the input buffer.
int l = 0;
while(l==0){ //Checking l
printf("Invalid input. Please enter a number.");
l = scanf("%f",&num1); //scanf will look at the buffer if the input
//does not match, it will not be consumed
//and will remain in buffer.
}
In other words, the character that doesn't match is never read. So when you type e.g. an a character, your code will loop indefinitely as scanf continues to fail on the same character.
When the program executes its last scanf("%f",&num2) call then because of the enter there is a newline \n character present in buffer and so due to ch = getchar(), new line \n gets stored in ch and the following if condition satisfies and the loop execute again.
if(ch =='\n')
continue;
while(scanf("%f",&num1)==0)
{
printf("Invalid input. Please enter a number.");
scanf("%f",&num1);
}
This loops scans two numbers per iteration. This is not what you want. Lose the second scanf.
You should also check for EOF and errors.
int result;
while((result = scanf("%f",&num1))==0)
{
printf("Invalid input. Please enter a number.");
}
if (result == EOF) .... report an error and exit ...

Logic Error in C Program on xcode

I have written this code for a grocery store.. This code makes perfect sense to me. However, I keep getting a logic error. Every time the user enters a bill and then presses -1 to exit, he is taken back to the main menu. When user presses choice 2 to EXIT program, the program is NOT exiting and he taken back to case 1 for some reason. Could you please help me? Thank you!
#include <stdio.h>
int main(void){
double prices[7];
prices[0]=2.55;
prices[1]=12.07;
prices[2]=2.00;
prices[3]=0.55;
prices[4]=5.35;
prices[5]=8.65;
prices[6]=2.55;
int choice;
int productCode;
int quantity;
char stop[3];
int compare;
double price;
double totalPrice=0;
do{
printf("\n1. Create new bill");
printf("\n2. EXIT");
printf("\n\nEnter choice: ");
choice=scanf("%d", &choice);
switch(choice){
case 1:{
do{
printf("\nEnter product code: ");
scanf("%d",&productCode);
printf("\nEnter quantity of product: ");
scanf("%d",&quantity);
price=prices[productCode]*quantity;
totalPrice=totalPrice+price;
printf("\nTo stop entering products enter -1.. to continue press any other character ");
scanf("%s", &stop);
compare=strcmp(stop, "-1");
}while(compare!=0);
break;
}
case 2: break;
default: printf("\nInvalid choice");
}
}while(choice!=2);
getchar();
return 0;
}
Instead of
choice=scanf("%d", &choice);
Do
scanf("%d", &choice);
scanf return value is:
On success, the function returns the number of items of the argument
list successfully filled. This count can match the expected number of
items or be less (even zero) due to a matching failure, a reading
error, or the reach of the end-of-file.
If a reading error happens or the end-of-file is reached while
reading, the proper indicator is set (feof or ferror). And, if either
happens before any data could be successfully read, EOF is returned.
If an encoding error happens interpreting wide characters, the
function sets errno to EILSEQ.
http://www.cplusplus.com/reference/cstdio/scanf/
for (;;){
printf("\n1. Create new bill");
printf("\n2. EXIT");
printf("\n\nEnter choice: ");
scanf("%d", &choice);
if(choice == 2 ){
break;
} else if(choice == 1){
do{
printf("\nEnter product code: ");
scanf("%d",&productCode);
printf("\nEnter quantity of product: ");
scanf("%d",&quantity);
price=prices[productCode]*quantity;
totalPrice=totalPrice+price;
printf("\nTo stop entering products enter -1.. to continue press any other character ");
scanf("%s", &stop);
compare=strcmp(stop, "-1");
}while(compare!=0);
} else {
printf("\nInvalid choice");
}
}

Resources