Why does this accept invalid input?

前端 未结 5 2152
一个人的身影
一个人的身影 2020-12-22 09:52

I have a triangle program in c

#include 

// A function which decides the type of the triangle and prints it
void checkTriangle(int s1, int s         


        
相关标签:
5条回答
  • 2020-12-22 09:58

    Read the input into a string buffer. Parse the string to extract numeric values be of any kind one by one.

    0 讨论(0)
  • 2020-12-22 09:59

    If you really want each number on a separate line of input, and for the whole of the line to be valid number or space, then you probably need to forget scanf() and family and use fgets() and strtol() instead.

    #include <stdlib.h>
    #include <errno.h>
    #include <stdio.h>
    #include <ctype.h>
    #include <limits.h>
    
    static int read_side(void)
    {
        char buffer[4096];
        if (fgets(buffer, sizeof(buffer), stdin) == 0)  // EOF
            return -1;
        char *end;
        errno = 0;
        long result = strtol(buffer, &end, 10);
        if (result < 0 || errno != 0) // Neither errors nor negative numbers are allowed
            return -1;
        if (end == buffer)     // Nothing was convertible
            return -1;
        while (isspace(*end))
            end++;
        if (*end != '\0')      // Non-spaces after the last digit
            return -1;
        if (result > INT_MAX)  // Result too big for `int`
            return -1;
        return result;
    }
    

    (If you needed to accept any valid int value but distinguish errors, then you'd pass in a pointer to the function and return -1 on error or 0 on success, and assign the safe result to the pointer.)

    Yes, it really is that fiddly to do the job properly. And yes, analyzing the result of strtol() is as tricky as that; you do have to be very careful. (And there's an outside chance I've forgotten to check for a detectable error condition.) And no, I don't think you can do the equivalent job with scanf() et al; in particular, the behaviour on overflow with scanf() is undefined.

    0 讨论(0)
  • 2020-12-22 09:59

    %d accepts only integer. try with %x in scanf() for hex-decimal input.

    Better you can get input as string then check using isnumeric() else use scanf("%[^\n]s", word) like @mou suggested.

    0 讨论(0)
  • 2020-12-22 10:07

    you shouldn't use scanf or do scanf("%[^\n]s", word); Or use someting like get() also put d or x at the end of my example not s for string :P

    0 讨论(0)
  • 2020-12-22 10:22

    If you want to be able to detect an error with the user's input, such as a line not being a valid decimal integer, then you could do the following:

    • Read the input into a buffer using fgets(buffer, size, stdin)
    • Use strtoul(buffer, &endptr, 10) to parse the buffer as a decimal integer (base 10), where endptr is a char*
    • endptr will point to the first invalid character in buffer, ie. the character after the last one which was successfully parsed
    • Now if *endptr == '\0', ie. endptr points to the end of buffer, the whole string was parsed as a valid decimal integer
    0 讨论(0)
提交回复
热议问题