This is my current programm in which i take 3 different (or the same) values of N Natural Numbers and calculate their checksum, the usage of long datatype is a must as i also need to be able to calculate the checksum of values that exceed the MAX of int. I cant change the datatype. Now I also need to catch when the user enters a a non natural numbers e.g -23, 2.3 ... Ive made if statements that catch if a negative number and a number that exceeds the MAX of long is entered, the actual problem is that when i enter decimal numbers it skips my if conditions and prints out the printf functions but not any of the other functions, ive tried catching the decimal number with x % 1 !=0 which does not work because the actual value of x doesnt seem to be stored as a decimal but rather a whole number , ive confirmed this in various places in my programm by printing the value of x. Im really new to C barely 2 weeks into studying and havent really grasped everything, but i really just cant seem to find the problem in my Programm. I know my code looks like spaghetti code.
P.S Excuse my awful english
#include <stdio.h>
#include <stdlib.h>
int checksum(long q){
long countingVariable = 0;
while(q > 0)
{
countingVariable = q; // steht für sx = s q
q/=10; // steht für q = q/10
}
return countingVariable;
}
int main(void) {
long x,y,z;
long long max_long = 2147483647;
printf("Bitte geben sie ihre erste Zahl ein:\n"); // enter first number
scanf("%ld",&x);
long sx = quersumme_1(x); // checksum of x first number
if ( x > 0 && x < max_long && x % 1 != 0){ // check if positive and natural number
printf("Bitte geben Sie ihre zweite Zahl ein:\n"); //enter second number
scanf("%ld",&y);
if (y > 0 && y < max_long){
long sy = quersumme_2(y); //checksum of y second number
printf("Bitte geben sie ihre dritte Zahl ein:\n");// enter third number
scanf("%ld",&z);
if (z > 0 && z < max_long){
long sz = quersumme_3(z); // checksum of z 3rd number
if (sx>sy && sx>sz && sy>=sz){
printf("Die Quersumme s der Zahl %ld ist %ld\n",x,sx);
printf("Die Quersumme s der Zahl %ld ist %ld\n",y,sy);
printf("die Quersumme s der Zahl %ld ist %ld\n",z,sz);
} else if (sx>sy && sx>z && sz>sy){
printf("Die Quersumme s der Zahl %ld ist %ld\n",x,sx);
printf("die Quersumme s der Zahl %ld ist %ld\n",z,sz);
printf("Die Quersumme s der Zahl %ld ist %ld\n",y,sy);
} else if (sy>sx && sy>sz && sx>=sz){
printf("Die Quersumme s der Zahl %ld ist %ld\n",y,sy);
printf("Die Quersumme s der Zahl %ld ist %ld\n",x,sx);
printf("die Quersumme s der Zahl %ld ist %ld\n",z,sz);
} else if (sy>sx && sy>sz && sz>sx){
printf("Die Quersumme s der Zahl %ld ist %ld\n",y,sy);
printf("die Quersumme s der Zahl %ld ist %ld\n",z,sz);
printf("Die Quersumme s der Zahl %ld ist %ld\n",x,sx);
} else if(sz>sx && sz>sy && sx>=sy){
printf("die Quersumme s der Zahl %ld ist %ld\n",z,sz);
printf("Die Quersumme s der Zahl %ld ist %ld\n",x,sx);
printf("Die Quersumme s der Zahl %ld ist %ld\n",y,sy);
} else if(sz>sx && sz>sy && sy>sx){
printf("die Quersumme s der Zahl %ld ist %ld\n",z,sz);
printf("Die Quersumme s der Zahl %ld ist %ld\n",y,sy);
printf("Die Quersumme s der Zahl %ld ist %ld\n",x,sx);
} else if (sx==sy && sx==sz && sy==sz){
printf("Die Quersumme s der Zahl %ld ist %ld\n",x,sx);
printf("Die Quersumme s der Zahl %ld ist %ld\n",y,sy);
printf("die Quersumme s der Zahl %ld ist %ld\n",z,sz);
}
// the big if tree is just a sorting "algorithm" it sorts the values of checksums
}if (z < 0){ //check for negative number z
printf("Falsche Eingabe: Minus Zahl"); //error
exit(0);
}if (z > max_long){ // cant exceed Max value of long
printf("Falsche Eingabe: Zahl overflowed long");// error
exit(0);
}
}if (y < 0){ //check for negative number y
printf("Falsche Eingabe: Minus Zahl"); // error
exit(0);
}if (abs(y) > max_long){ // cant ewxceed max value of long
printf("Falsche Eingabe: Zahl overflowed long"); /error
exit(0);
}
}if (x < 0){ //check for negative numbers
printf("Falsche Eingabe: Minus Zahl"); // error
printf("%ld",x);
exit(0);
}
if (x > max_long){ // cant exceed max of long
printf("Falsche Eingabe: Zahl overflowed long"); // error
exit(0);
}
return 0;
}
CodePudding user response:
A long
type can not store a decimal value, and scanf
will always try to match what the user entered to the type of value you told it to expect.
In your case, %ld
means that if user enters a decimal number, scanf
will ignore it, and not put anything in y
.
There are two ways to deal with this in C:
Read a string from the user and check the characters in it to make sure they are all digits (or that there is no decimal point or whatever else you need to check).
Then you can useatol
to convert the string tolong
.Check the value
scanf
returns.
scanf
returns how many items from the user it matched to your expectations and stored in the variables you provided.
In your case it should return 1 if a valid integer was entered.
This method won't tell you if the user entered a decimal number or a word instead of a natural number, but you will know if the input was valid or not.
CodePudding user response:
The best is to use fgets()
read the line of user input into a string and then parse the string.
Let us say you are stuck with scanf()
(too bad).
First, check return value
// scanf("%ld",&y);
if (scanf("%ld",&y) != 1) {
printf("Non-numeric input");
exit(0);
}
Now read the next character
unsigned char ch;
if (scanf("%c",&ch) != 1) {
printf("Failed to read next character");
exit(0);
}
if (!isspace(ch)) {
printf("Unexpected character following a number %d %c\n", ch, ch);
exit(0);
}
Now check for range
if (y < min_long || y > max_long) {
printf("Out of range %ld\n", y);
exit(0);
}
Simplifications exist.
Again better to use fgets()
.
A robust, but unchecked, example:
#define LINE_SZ 100 // Max expected line size
char buf[LINE_SZ * 2]; // Let us read even up to 2x expected
if (fgets(buf, sizeof buf, stdin) == NULL) {
printf("Nothing read\n", y);
exit(EXIT_FAILURE);
}
errno = 0;
char *endptr;
long y = strtol(buf, &endptr, 0);
if (buffer == endptr) {
printf("Non-numeric input \"%s\"\n", buf);
exit(EXIT_FAILURE);
}
if (errno || y < long_min || long_max) {
printf("Input \"%s\" outside [%ld %ld] range\n", buf, long_min, long_max);
exit(EXIT_FAILURE);
}
// Skip trailing white-space
while (isspace((unsigned char)*endptr)) {
endptr ;
}
if (*endptr) {
printf("Trailing junk in \"%s\"\n", buf);
exit(EXIT_FAILURE);
}
printf("Success %ld\n", y);