Home > OS >  Trying to catch if the entered value stored in long is a decimal number C
Trying to catch if the entered value stored in long is a decimal number C

Time:12-17

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:

  1. 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 use atol to convert the string to long.

  2. 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);
  •  Tags:  
  • c
  • Related