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
Read the input into a string buffer. Parse the string to extract numeric values be of any kind one by one.
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.
%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.
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
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:
fgets(buffer, size, stdin)
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*endptr == '\0'
, ie. endptr
points to the end of buffer
, the whole string was parsed as a valid decimal integer