Is it right to use a "for" loop to create a loop that check input value? - c

I need to write a program that requests two floating-point numbers and prints the value of
their difference divided by their product, and to have the program loop through pairs of
input values until the user enters nonnumeric input. I need to use scanf to take the input.
So, as I know that scanf return a value 0 or 1 for true/false so I though testing it to accomplish the last part of the question, but I'm trying to figure out how to make sure the loop goes back to ask for input.
My code is:
int main()
{
double num1, num2, different, product, answer;
printf("please enter 2 floatig point numbers:\n");
printf("number one is?\n");
while (scanf("%lf", &num1) ==1)
{
printf("number two is?\n");
while (scanf("%lf", &num2) ==1)
{
if (num1 > num2)
{
different = num1 - num2;
}
if (num2 > num1)
{
different = num2 - num1;
}
if (num1 == num2)
{
different = 0;
}
product = num1*num2;
answer = different/product;
printf("%lf", answer);
}
printf("you're out!");
}
printf("you're out!");
}
Example input:
first num 4.5
second num 3.5
output:
please enter 2 floatig point numbers:
number one is?
4.5
number two is?
3.5
0.063492
I'm getting the right answer and the program keeps running but I'm looking for a solution to go back for the input request.

You should first note that whatever made your scanf fail the first time, will probably make it fail the second time. So a loop such as this:
while (scanf("%lf", &a) != 1);
could become an infinite loop.
Also, when reading two or more values at the same time, it would be hard to track what is read and what is not. Therefore, I advise reading the values one by one, in a form like this:
void clear_line()
{
char c;
while (scanf("%c", &c) == 1)
if (c == '\n')
return;
}
double read_value(const char *message)
{
double d;
while (1)
{
printf("%s", message);
if (scanf("%lf", &d) == 1)
return d;
if (feof(stdin))
{
printf("Unexpected end of file\n");
return 0;
}
printf("Invalid input\n");
clear_line();
}
}
...
num1 = read_value("Enter first number: ");
num2 = read_value("Enter second number: ");
if (feof(stdin))
/* handle error */
What this basically does is try reading the value until the user produces a correct one. In case of incorrect input, one line of input is consumed and thrown away so the left over of whatever the user has input would not affect the next scanf and create a chain of errors.

Its just simply a pattern to define the number of input are you wanting. the simpler version of your code is
while( scanf("%d %d", &a,&b) == 2 )
//
here scanf return the 2 as a return value.
so you are checking while(2 == 2), make the number of input are you wanting
while( scanf("%lf %lf", &num1,&numb2) == 2 )
{
if (num1 > num2)
{
different = num1 - num2;
}
if (num2 > num1)
{
different = num2 - num1;
}
if (num1 == num2)
{
different = 0;
}
product = num1*num2;
}

You can simply do it like:
while(1)
{
printf("number one is?\n");
if(scanf("%lf", &num1) != 1)
{
break;
}
printf("number teo is?\n");
if(scanf("%lf", &num2) != 1)
{
break;
}
if (num1 > num2)
{
different = num1 - num2;
}
if (num2 > num1)
{
different = num2 - num1;
}
if (num1 == num2)
{
different = 0;
}
product = num1*num2;
answer = different/product;
printf("%lf", answer);
}
}

Related

When inputting large numbers it returns the final result as NaN

I am creating a SUPER basic calculator in C for a project.
/*
Declare and initialize variables and/or constants using appropriate data types -- X
Read in input from the user and output data & information to the user in a meaningful manner -- X
Use the mathematical operators – addition, subtraction, multiplication, division, and modulus (remainder)
– in expressions and calculations -- X
Use decision making structures such as if, if/else, and switch to affect program flow -- X
Use control structures such a while, do-while, and for loops to implement repetition in code -- X
*/
//All libraries
#include <stdio.h>
#include <stdbool.h>
#include <ctype.h>
float num1 = 0;
float num2 = 0;
float finalResult = 0;
char operator = '+';
bool opReal = false;
int main() {
//Ask for first number
printf("Enter an number: ");
scanf("%f", &num1);
printf("\n");
//Ask for second number
printf("Enter another number: ");
scanf("%f", &num2);
printf("\n");
//Ask for operator
do {
printf("Enter either + - * or /: ");
scanf(" %c", &operator);
//Check for what operator is
if (operator == '-') {
operator = '-';
opReal = true;
} else if (operator == '+') {
operator = '+';
opReal = true;
} else if (operator == '*') {
operator = '*';
opReal = true;
} else if (operator == '/') {
operator = '/';
opReal = true;
} else {
operator = '+';
opReal = false;
}
} while (!opReal);
printf("num1: %f\n", num1);
printf("num2: %f\n", num2);
printf("operator: %c\n", operator);
//Do calculations
if (operator == '-') {
finalResult = num1 - num2;
} else if (operator == '+') {
finalResult = num1 + num2;
} else if (operator == '*') {
finalResult = num1 * num2;
} else if (operator == '/') {
finalResult = num1 / num2;
}
printf("Final Result: %f\n", finalResult);
}
I've tried looking up different solutions and applying different ways to operate on num1 and 2, but in the end they don't work.
It should take num1 and num2 and apply operator to it.
However when a large number is applied then num1 = inf and num2 = inf.
That in turn makes finalResult Nan
Whats happening?
Please help.
Well depending on how large those large numbers are, you might just be able to replace "float" with "double" and have it work.
Other than that you could add the following check to your code:
if(isinf(num1) || isinf(num2) || isnan(num1) || isnan(num2)) {
printf("Error, number out of bounds!");
return -1;
}
Though this requires the use of #include <math.h> though, if you are constrained to just the libraries specified in this file (as might be implied by the comment) then this might just be an unsolvable problem.
I don't see anything particular wrong with your code so maybe you just need to switch from float to double or even long double? Don't use global variable unless you have to. Guard against divide by zero. No point of checking if an operator is x then assign x to the operator. Check that scanf() was successful otherwise you may be operating on uninitialized data.
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
int main() {
double num1;
printf("Enter a number: ");
if(scanf("%lf", &num1) != 1) {
printf("scanf failed\n");
return 1;
}
double num2;
printf("Enter another number: ");
if(scanf("%lf", &num2) != 1) {
printf("scanf failed\n");
return 1;
}
char operator;
do {
printf("Enter either + - * or /: ");
if(scanf(" %c", &operator) != 1) {
printf("scanf failed\n");
return 1;
}
} while (!strchr("-+*/", operator));
double finalResult = 0;
if (operator == '-') {
finalResult = num1 - num2;
} else if (operator == '+') {
finalResult = num1 + num2;
} else if (operator == '*') {
finalResult = num1 * num2;
} else if (operator == '/') {
finalResult = num2 != 0 ? num1 / num2 : 0; // or ERR?
}
printf("Final Result: %lf\n", finalResult);
}
I would use an array of numbers, dedup the input with a loop and probably a switch instead of all those if-else-if:
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#define NUM_LEN 2
int main() {
const char *prompts[NUM_LEN] = { "an", "another" };
double num[NUM_LEN];
for(size_t i = 0; i < NUM_LEN; i++) {
printf("Enter %s number: ", prompts[i]);
if(scanf("%lf", &num[i]) != 1) {
printf("scanf failed\n");
return 1;
}
}
char operator;
do {
printf("Enter either + - * or /: ");
if(scanf(" %c", &operator) != 1) {
printf("scanf failed\n");
return 1;
}
} while (!strchr("-+*/", operator));
switch(operator) {
case '-':
num[0] -= num[1];
break;
case '+':
num[0] += num[1];
break;
case '*':
num[0] *= num[1];
break;
case '/':
num[0] = num[1] != 0 ? num[0] / num[1] : 0; // or ERR?
break;
default:
printf("Invalid operator\n");
break;
}
printf("Final Result: %lf\n", num[0]);
}
The next step would be to build a map from operator to a function, i.e:
struct operators {
char operator;
int (*evaluate)(double *num);
} operators[] = {
{'+', add},
{'-', subtract},
{'*', multiply},
{'/', divide}
};
Now you extract the valid operators used in strchr() from this map, and you can use lfind() to lookup the evaluate function for a given operator.

autocheck gives me memory and runtime error even though my program runs perfectly

for Uni I have to program a little Calculator think which has to go through a automatic check and be approved for me to pass the test. oblem is that for some reason everything runs perfectly fine in my IDE, there's no Errors, no warning and even debugging i couldn't find any problems but the automatic check gives me 2 errors in my division function which looks like this:
int divis(int num1, int num2) {
int rest;
rest = 0;
char opt;
opt = 'X';
rest = num1 % num2; //calc remainder
printf("\nDivision has remainder %d. Round (r), cut off (c) or discard (d)?", rest); //print remainder
while((opt =! 'd') || (opt != 'c') || (opt != 'r')){
printf("\nOption: ");
scanf(" %c", &opt);
if(opt == 'r'){ //round
if(rest * 2 < num2){
num1 = num1 / num2; //calc result
rest = 0;
printf("\nResult: %d", num1); //print result
break;
}
else {
num1 = num1 / num2; //calculate result
++num1; //+round up
rest = 0;
printf("\nResult: %d", num1); //print result
break;
}
}
else if(opt == 'c'){ //calculate remainder
rest = 0;
num1 = num1 / num2; //calculate result
printf("\nResult: %d", num1); //print result
break;
}
else if(opt == 'd'){ //discard operation
printf("\nNo new result");
break;
}
else
printf("\nUnknown option\n");
}
if(num1 >= 0)
++poscount;
else
++negcount; //count results
return num1;
}
keep in mind that it's an exercise in which i need to follow all the required steps. For the calculation 32 / 8 the automatic check gives me the Error: ** <<>> MemoryError **
A memory error occured during program execution.
Please check your program for illegal memory accesses. and for 32 / -8 it gives me a runtime error even though my program runs perfectly fine. I've been doing some research on the internet for hours but nothing i tried helped. I would really apreciate your help

Scanf() not working correctly in C when inputting value

I'm trying to work on a program to input a phone number and test if it is the right amount of digits in C, also checking if the first value is not 0 or 1. Scanf is not taking a value when I enter it and I do not understand why. If someone could please point out to me what the issue is it'd be much appreciated.
#include <stdio.h>
int main (void){
int number = 0;
int loop = 0;
while(loop == 0){
printf("Enter a phone number: ");
scanf(" %d ", &number);
printf("%d", number);
int firstDigit;
while(number >= 10){
firstDigit = number/10;
}
if((number/1000000) >= 1 && (number/1000000) < 10){
if(firstDigit == 1){
printf("Invalid central office code: 1");
}
else if(firstDigit == 0){
printf("Invalid central office code: 0");
}
else{
int firstThree = (number/10000);
int lastFour = (number%10000);
printf("%d - %d", firstThree, lastFour);
}
}
else if(number == 0){
printf("Exiting.");
loop = 1;
}
else{
if((number/1000000)>=10){
printf("Invalid phone number: too many digits");
}
else if((number/1000000)<1){
printf("Invalid phone number: too few digits");
}
}
}
return 0;
}
This:
while(number >= 10) {
firstDigit = number/10;
}
is an infinite loop, because you are not modifying number.
What you probably want to do is:
while(number >= 10) {
firstDigit = number/10;
number /= 10;
}
You should avoid scanf() to read input. Better use fgets(), and then sscanf() for parsing.
char input[1024]; // This should be large enough
if (!fgets(input, sizeof input, stdin)) {
printf("Input error\n");
return 1;
}
input[strcsnp(input, "\n")] = '\0'; // Because fgets reads \n so remove it
if (sscanf(input, "%d", &number) != 1) {
printf("Parsing error\n");
return 1;
}
// Use number...
Also, scanf() and sscanf() "ignore" the first 0s you type as part of the phone number, so your solution might not be correct. The best way to represent a phone number is either by storing it as a string (as mentioned in a comment), or by defining a phone number structure.
Int size in c is 4 bytes, which can hold values only -2,147,483,648 to 2,147,483,647.
It can't store all 10 digit values.
you can use long
long number = 0;
scanf("%ld", &number);
printf("%ld", number);

Printf command after an if statement does not work

I just started programming a couple of days ago. I tried to program something that calculates my CGPA. I haven't completed it yet; for example, I have to improve the menu etc. It works properly for the 1st and 3rd choice. I will do something else for the second choice. The problem is, after calculation, it doesn't print the text "qwerty" on the bottom.
#include <stdio.h>
#include <stdlib.h>
int main()
{
char h[2];
double numGrade;
double credit, percent, overallCredit, sumCredit;
double contribution=0, GPA=0, semGPA=0, CGPA=0;
int courseNum, i, semesters, k, menu;
printf("Input\n\"1\" for computing your CGPA\n\"2\" if you know each semester's GPA\n\"3\" if you know your CGPA\n");
scanf("%d", &menu);
if(menu == 1)
{
printf("Enter the number of semesters you have studied: ");
scanf("%d", &semesters);
for(k=1; k<=semesters; k++)
{
printf("Enter the number of courses you took in semester %d: ", k);
scanf("%d", &courseNum);
overallCredit = 0;
sumCredit = 0;
for(i=1; i<=courseNum; i++)
{
printf("Enter the credit of the course %d: ", i);
scanf("%lf", &credit);
overallCredit += credit;
printf("Enter your letter grade: ");
scanf("%s", h);
if(strcmp(h, "AA") == 0)
{
numGrade = 4.0;
}else if(strcmp(h, "BA") == 0)
{
numGrade = 3.5;
}else if(strcmp(h, "BB") == 0)
{
numGrade = 3.0;
}else if(strcmp(h, "CB") == 0)
{
numGrade = 2.5;
}else if(strcmp(h, "CC") == 0)
{
numGrade = 2.0;
}else if(strcmp(h, "DC") == 0)
{
numGrade = 1.5;
}else if(strcmp(h, "DD") == 0)
{
numGrade = 1.0;
}else if(strcmp(h, "FD") == 0)
{
numGrade = 0.5;
}else if(strcmp(h, "DD") == 0)
{
numGrade = 0.0;
}else
{
printf("Invalid Grade\n");
}
percent = numGrade/4.0;
contribution = percent*credit;
sumCredit += contribution;
}GPA = (sumCredit/overallCredit)*4.0;
printf("Your GPA for semester %d is: %f\n", k, GPA);
semGPA += GPA;
}CGPA = semGPA/semesters;
printf("CGPA is: %.2f", CGPA+0.005);
}else
{
printf("Enter your CGPA: ");
scanf("%lf", &CGPA);
printf("Your CGPA is: %.2f", CGPA+0.005);
}
printf("qwerty"); //This does not print.
return 0;
}
The problem here is that you're running into undefined behaviour! (This means anything can happen - code will work, sometimes, not work, sometimes, and maybe even wipe your hard disk, sometimes.)
This happens because you are trying to read too many characters into your h variable: you have declared it: char h[2], which can hold only one letter plus the terminating nul. But you try to read two letters into it. Declare it a bit longer: char h[3] and your code should work. But it's maybe better to be safer, and declare it longer, say char h[20];, in case the user types too much data in; alternatively, specify in the input format a maximum string length: scanf("%2s", h);, which will truncate (ignore) any letters after the second.
In your code, the scanf operation writes beyond the memory allocated to h and, thus, maybe changes other 'control' variables in the compiled code.
EDIT: PS, it may not actually be the scanf call that triggers the undefined behaviour! It could be the subsequent strcmp call - the h argument to this will not have a nul terminator and the function will then overflow the string buffer, looking for a zero.

Problems in C code

I am trying to make a simple calculator in Turbo C(I have my own reasons to why I use Turbo C now)
#include <stdio.h>
#define P printf
int loop[] = {1, 1, 1, 1};
int num;
char input[64];
void main()
{
int num1, num2;
char x, y;
while(loop[0] == 1)
{
clrscr();
P("Hello!, This simple calculator will help you compute 2 numbers.");
P("\nPress the corresponding key to choose the operation you will use.");
P("\n\nA - (A)ddition");
P("\nS - (S)ubtraction");
P("\nM - (M)ultiplication");
P("\nD - (D)ivision");
P("\n\nAnswer: ");
while(loop[1] == 1)
{
x = getchar();
if(tolower(x) == 'a')
{
P("\nYou have chosen addition.");
num1 = askForNumber("\n\nEnter 1st number: ");
num2 = askForNumber("\nEnter 2nd number: ");
P("\n\n%d + %d = %d", num1, num2, num1+num2);
}
else if(tolower(x) == 's')
{
P("\nYou have chosen subtraction.");
num1 = askForNumber("\n\nEnter 1st number: ");
num2 = askForNumber("\nEnter 2nd number: ");
P("\n\n%d - %d = %d", num1, num2, num1-num2);
}
else if(tolower(x) == 'm')
{
P("\nYou have chosen multiplication.");
num1 = askForNumber("\n\nEnter 1st number: ");
num2 = askForNumber("\nEnter 2nd number: ");
P("\n\n%d * %d = %d", num1, num2, num1*num2);
}
else if(tolower(x) == 'd')
{
P("\nYou have chosen division.");
num1 = askForNumber("\n\nEnter 1st number: ");
num2 = askForNumber("\nEnter 2nd number: ");
P("\n\n%g* %g = %.2f", (float)num1, (float)num2, (float)(num1/num2));
}
else
{
P("\nYou have entered an invalid character!");
P("\n\nAnswer: ");
continue;
}
while(loop[2] == 1)
{
P("\n\nDo you want to do another calculation? Y/N: ");
y = getchar();
if(tolower(y) == 'y' || tolower(y) == 'n')
{
loop[2] = 0;
}
else
{
P("\nYou have entered an invalid character.");
continue;
}
}
loop[1] = 0;
}
if(tolower(y) == 'y')
{
continue;
}
if(tolower(y) == 'n')
{
loop[0] = 0;
}
}
}
int askForNumber(const char *string)
{
P("%s", string);
while(loop[3] == 1)
{
fgets(input, (sizeof(input)/sizeof(input[0]))-1, stdin);
if(sscanf(input, "%d", &num) != 1)
{
num = 0;
P("Invalid number!");
continue;
}
return num;
}
}
I have these bugs:
After I finish a calculation, and press 'Y', it clears the screen non-stop.
After "Enter 1st number: ", the "Invalid number" shows up once even though I haven't typed anything yet(but i can still input a number and it will be saved to 'num1', "Invalid number just bugs me".
At the top where I am to input 'a' or 's' or 'm' or 'd' to choose an operation, if I put some letter except for that above, i get this
OUTPUT:
Answer: o
You have entered an invalid character!
Answer:
You have entered an invalid character!
Answer:
the error shows up twice, but i only typed once.
When there are no characters in the input buffer, the getchar function blocks until the return key is pressed. All keys, including return, are stored in the input buffer, then getchar returns the first character in the buffer. The next call to getchar will immediately return the next character in the buffer.
So if you press 'y' then return, the first call to getchar returns the 'y' character, and the next returns a newline character, i.e. the return key.
You need to flush the input buffer each time you use getchar to skip over the newline:
do {
c = getchar();
} while (c == '\n');
You nedd #include ctype.h to lower is part of that library tolower uses this library and its nowhere in your code

Resources