Home > Software engineering >  How NOT to read float type in scanf when reading type int
How NOT to read float type in scanf when reading type int

Time:07-07

I need to write two integers (and nothing else) to variables. It does the validation makes sure that none of args is a string and that they are not empty and excepts division by zero, or when i put float as a first arg but when i put float as a second argument it does not makes an exception. How can i solve it using only stdio.h?

#include <stdio.h>

void sum(int a, int b);

void dif(int a, int b);

void prod(int a, int b);

void qut(int a, int b);

int main() {
  int x, z;
  int digits = scanf("%d %d", &x, &z);
  if (digits != 2) {
    printf("n/a\n");
    return 2;
  }
  else {
    sum(x, z);
    dif(x, z);
    prod(x, z);
    qut(x, z);
  }
  return 0;
}

void sum(int a, int b) {

  printf("%d ", a   b);
}

void dif(int a, int b) {

  printf("%d ", a - b);
}

void prod(int a, int b) {

  printf("%d ", a * b);
}
 
void qut(int a, int b) {

  if (a == 0 || b == 0) {
    printf("n/a\n");
  }
  else {
    printf("%d\n", a / b);
  }
}

Sorry, i understand that the code is quiet simple and my question is quiet dumb :) Thx!

CodePudding user response:

As mentioned in the comments, scanf is the WRONG TOOL for this job. scanf is notoriously bad at error handling.

Theoretically it's possible — barely possible — to solve this problem using scanf. By the same token, it's possible to drive a screw into a piece of wood using a hammer. But it's a terrible idea. A woodshop teacher who taught his students to drive screws using a hammer would be fired for incompetence. But for some reason we tolerate this kind of incompetence in teachers of beginning programming.

Normally I don't do homework problems here; normally that's a bad idea, too; normally it makes much more sense to have you, the student, do the work and acquire the learning. In the case of boneheaded assignments like this one, though, I have no qualms about giving you a fully-worked-out solution, so you can get your incompetent instructor off your back and go on to learn something more useful. Here is the basic idea:

  1. Read a line of text (a full line), using fgets.
  2. Parse that line using sscanf, ensuring that it contains a number and a number, and nothing else.
  3. Specifically, we'll use %d to read the first integer, and %d to read the second integer, and then we'll use a third %c to pick up whatever character comes next. If that character is anything other than the \n that marks the end of the line, it indicates that the user has typed something wrong, like a string, or the . that's part of a floating-point number.

This is basically the same as user3121023's solution.

int main()
{
    char line[100];
    int x, z;
    char dummy;

    if(fgets(line, sizeof(line), stdin) == NULL) return 1;
    int digits = sscanf(line, "%d%d%c", &x, &z, &dummy);
    if(digits < 2 || digits > 2 && dummy != '\n') {
        printf("n/a\n");
        return 2;
    }

    ...

See also What can I use for input conversion instead of scanf?

Footnote: The code here has one unfortunate little glitch: If the user types a space after the second number, but before the newline, the code will reject it with n/a. There are ways to fix that, but in my opinion, for this exercise, they're just not worth it; they fall under the "law of diminishing returns". If your users complain, just act like incorrigible software vendors everywhere: remind them that they were supposed to type two numbers and nothing else, and the space they typed after the second number is "something else", so it's THEIR FAULT, and not your bug. :-)

CodePudding user response:

After scanning for the integers, use a loop to scan for one whitespace character. Break out of the loop on a newline.
For any other character, the scan will return 0.

#include <stdio.h>

void sum(int a, int b);
void dif(int a, int b);
void prod(int a, int b);
void qut(int a, int b);

int main() {
    char ws[2] = ""; // whitespace
    int scanned = 0;
    int x, z;
    int digits = scanf("%d %d", &x, &z);
    if (digits != 2) {
        printf("n/a\n");
        return 2;
    }
    while ( ( scanned = scanf( "%1[ \t\n]", ws))) { // scan for 1 whitespace
        if ( scanned == EOF) {
            fprintf ( stderr, "EOF\n");
            return 1;
        }
        if ( ws[0] == '\n') {
            break;
        }
    }
    if ( scanned != 1 || ws[0] != '\n') {
        printf("n/a\n");
        return 3;
    }
    else {
        sum(x, z);
        dif(x, z);
        prod(x, z);
        qut(x, z);
    }
    return 0;
}

void sum(int a, int b) {
    printf("%d ", a   b);
}

void dif(int a, int b) {
    printf("%d ", a - b);
}

void prod(int a, int b) {
    printf("%d ", a * b);
}

void qut(int a, int b) {
    if (a == 0 || b == 0) {
        printf("n/a\n");
    }
    else {
        printf("%d\n", a / b);
    }
}
  • Related