...
This noncompliant code example converts the string token stored in the static array buff
to a signed integer value using the atoi()
function.:
Code Block | ||||
---|---|---|---|---|
| ||||
int si; if (argc > 1) { si = atoi(argv[1]); } |
...
Unfortunately, atoi()
and related functions lack a mechanism for reporting errors for invalid values. Specifically, the atoi()
, atol()
, and atoll()
functions
- do Do not need to set
errno
on an error. - have Have undefined behavior if the value of the result cannot be represented. (See undefined behavior 119 of Annex J of the C Standard.)
- return Return 0 if the string does not represent an integer (which is indistinguishable from a correctly formatted, zero-denoting input string), but the C Standard only specifies the behavior of these functions on success.
...
This compliant solution uses strtol()
to convert a string token to an integer and ensures that the value is in the range of int
.:
Code Block | ||||
---|---|---|---|---|
| ||||
long sl; int si; char *end_ptr; if (argc > 1) { errno = 0; sl = strtol(argv[1], &end_ptr, 10); if ((sl == LONG_MIN || sl == LONG_MAX) && errno != 0) { perror("strtol error"); } else if (end_ptr == argv[1]) { if (puts("error encountered during conversion") == EOF) { /* Handle Error */ } } else if (sl > INT_MAX) { printf("%ld too large!\n", sl); } else if (sl < INT_MIN) { printf("%ld too small!\n", sl); } else if ('\0' != *end_ptr) { if (puts("extra characters on input line\n") == EOF) { /* Handle Error */ } } else { si = (int)sl; } } |
...
This noncompliant code example sets the file position indicator of an input stream back to the beginning using rewind()
.:
Code Block | ||||
---|---|---|---|---|
| ||||
char *file_name; FILE *fp; /* Initialize file_name */ fp = fopen(file_name, "r"); if (fp == NULL) { /* Handle open error */ } /* Read data */ rewind(fp); /* Continue */ |
...
This compliant solution uses fseek()
instead of rewind()
and checks to see if the operation succeeded.:
Code Block | ||||
---|---|---|---|---|
| ||||
char *file_name; FILE *fp; /* Initialize file_name */ fp = fopen(file_name, "r"); if (fp == NULL) { /* Handle open error */ } /* Read data */ if (fseek(fp, 0L, SEEK_SET) != 0) { /* Handle repositioning error */ } /* Continue */ |
...
This noncompliant code example calls setbuf()
with a buf
argument of NULL
.:
Code Block | ||||
---|---|---|---|---|
| ||||
FILE *file; /* Setup file */ setbuf(file, NULL); /* ... */ |
...
This compliant solution calls setvbuf()
, which returns nonzero if the operation failed.:
Code Block | ||||
---|---|---|---|---|
| ||||
FILE *file; char *buf = NULL; /* Setup file */ if (setvbuf(file, buf, buf ? _IOFBF : _IONBF, BUFSIZ) != 0) { /* Handle error */ } /* ... */ |
...
[Klein 2002] | "Bullet Proof Integer Input Using strtol() |
...