0

it is my first semester learning C programming and I am trying to limit the user input to 22 bit signed integer and if command doesn't work for some reason I tried changing the second if statement with an else but that didnt do anything

   #include <stdio.h>
#include <stdlib.h>
void main ( int argc, char *argv[] )
{
    
    int first;
    int second;
    char menu_choice;
    if(first>=2097150|| first<=-2097150|| second<=-2097150||second>=2097150)
        {
            printf("please choose a number between -2097150 and 2097150");
            return(0);
        }
        if(first<=2097150|| first>=-2097150|| second>=-2097150||second<=2097150)
        {//rest of the code goes here but that is not part of the problem
}
  • 3
    `first` is indeterminate at the point where you test it. There is no input being done. – Amadan Mar 23 '21 at 03:12
  • 1
    I don't have a simple solution for limiting the input to 22 bits, but you can limit the number of digits read: `scanf("%6d", &n);` – Andy Sukowski-Bang Mar 23 '21 at 03:13
  • @Amadan first and second are typed when running the ./a.exe (23,34 or whatever) – gobble1gobble Mar 23 '21 at 03:46
  • If you type `./a.exe 23 34`, they will be available as strings in `argv`; `first` and `second` know nothing about it. You would need to convert them, and assign the values to `first` and `second`; this should do the trick: `first = atoi(argv[1]); second = atoi(argv[2]);` – Amadan Mar 23 '21 at 03:49
  • The simplest way to get it going is to just change `int first; int second;` to `int first = atoi(argv[1]); int second = atoi(argv[2]);` and then first and second will have values. – Jerry Jeremiah Mar 23 '21 at 04:02
  • using int first; int second; to int first = atoi(argv[1]); int second = atoi(argv[2]); and adding an exit(0); worked. thank you so much – gobble1gobble Mar 23 '21 at 04:09
  • Assuming a *twos-compliment* representation of negative number, a 22 bit signed integer ranges from `-2097152 -> 2097151` (updated, was off-by-one in the earlier comment) See [min and max value of data type in C](https://stackoverflow.com/q/2053843/3422102)) – David C. Rankin Mar 23 '21 at 04:41

1 Answers1

0

If you are going to take any input, it always works the same way. You job is to require the user to provide a valid input and handle all cases where the input is not valid. You have two options: (1) read each line of input at a time with fgets() and then extract the value from the buffer filled with sscanf() (or strtol()), or (2) read the input value with scanf() directly and manually empty stdin after each input to remove any extraneous characters. Both are ultimately equivalent in what they do.

Whether reading the input with fgets() or scanf(), you must check whether the user generated a manual EOF by pressing Ctrl + d (or Ctrl + z on windows).

If you use scanf() or sscanf(), you must validate (1) that a valid integer value was provided and (2) it is within the range of a 22-bit signed value.

The way you require the user to enter the input you need is you Loop Continually until the user provides valid input. After the input satisfies all of your criteria, then, and only then, do you exit the input loop.

Putting it altogether, you could do something similar to:

#include <stdio.h>

#define MAXSIGNED22  0x1FFFFF       /* if you need a constant, #define one (or more) */
#define MINSIGNED22  -(MAXSIGNED22) - 1

int main (void) {
    
    int value = 0;          /* value to hold input */
    
    for (;;) {              /* loop continually until good input or manual EOF */
        int rtn;            /* return for scanf() */
        fputs ("enter a 22-but signed number: ", stdout);       /* prompt for input */
        rtn = scanf ("%d", &value);                 /* read with scanf(), save return */
        
        if (rtn == EOF) {   /* check for manual EOF */
            puts ("(user canceled input)\n");
            return 0;
        }
        /* empty any extraneous characters from stdin */
        for (int c = getchar(); c != '\n' && c != EOF; c = getchar()) {}
        
        /* check matching failure */
        if (rtn == 0)
            fputs ("  error: invalid integer value.\n", stderr);
        /* validate in range of 22-bit */
        else if (value < MINSIGNED22 || MAXSIGNED22 < value)
            fputs ("  error: value out of range for 22-bit.\n", stderr);
        /* good 22-bit value, break loop */
        else
            break;
    }
    
    printf ("\nvalid 22-bit signed number: %d\n", value);
}

Assuming a twos-compliment representation of negative numbers, the valid range of a signed 22-bit number is -2097152 -> 2097151. See min and max value of data type in C

Example Use/Output

$ ./bin/22bit
enter a 22-but signed number: 12345678
  error: value out of range for 22-bit.
enter a 22-but signed number: -12345678 (and other junk)
  error: value out of range for 22-bit.
enter a 22-but signed number: bananas!
  error: invalid integer value.
enter a 22-but signed number: 2097152
  error: value out of range for 22-bit.
enter a 22-but signed number: 2097151

valid 22-bit signed number: 2097151

and

$ ./bin/22bit
enter a 22-but signed number: -2097153
  error: value out of range for 22-bit.
enter a 22-but signed number: -2097152

valid 22-bit signed number: -2097152

Look things over and let me know if you have any questions.

David C. Rankin
  • 81,885
  • 6
  • 58
  • 85