fork download
  1. #include <errno.h> /* errno, EINVAL, ERANGE */
  2. #include <limits.h> /* INT_MIN, INT_MAX */
  3. #include <stdio.h> /* printf(), fprintf(), stderr */
  4. #include <stdlib.h> /* strtol() */
  5. #include <string.h> /* strerror() */
  6.  
  7. /* Convert a string to an int. */
  8. int
  9. str_to_int_strtol(const char *s)
  10. {
  11. char *s_rem;
  12. long l;
  13. int errno_save = errno;
  14.  
  15. errno = 0;
  16. l = strtol(s, &s_rem, 10);
  17. if (errno == 0) {
  18. /* Number out of range. */
  19. if (l < INT_MIN || l > INT_MAX)
  20. errno = ERANGE;
  21.  
  22. /* Argument isn't completely made up of decimal digits. */
  23. else if (*s_rem != '\0')
  24. errno = EINVAL;
  25. }
  26. if (errno) {
  27. fprintf(stderr, "strtol() error: operand \"%s\": %s\n", s,
  28. strerror(errno));
  29. return 0;
  30. }
  31.  
  32. errno = errno_save;
  33. return (int)l;
  34. }
  35.  
  36. /* Convert a string to an int (less robust). */
  37. int
  38. str_to_int_atoi(const char *s)
  39. {
  40. int n;
  41. int errno_save = errno;
  42.  
  43. errno = 0;
  44. n = atoi(s);
  45.  
  46. if (errno != 0) {
  47. fprintf(stderr, "atoi() error: operand \"%s\": %s\n", s,
  48. strerror(errno));
  49. return 0;
  50. }
  51.  
  52. errno = errno_save;
  53. return n;
  54. }
  55.  
  56. int
  57. main(void)
  58. {
  59. const char *s = "123hello";
  60. int n;
  61.  
  62. fprintf(stderr, "[====atoi()====]\n");
  63. n = str_to_int_atoi(s);
  64. printf(" n: %d\nerrno set: %s\n\n", n, errno != 0 ? "Yes" : "No");
  65.  
  66. errno = 0;
  67.  
  68. fprintf(stderr, "[===strtol()===]\n");
  69. n = str_to_int_strtol(s);
  70. printf(" n: %d\nerrno set: %s\n\n", n, errno != 0 ? "Yes" : "No");
  71.  
  72. return 0;
  73. }
Success #stdin #stdout #stderr 0s 2008KB
stdin
Standard input is empty
stdout
        n: 123
errno set: No

        n: 0
errno set: Yes

stderr
[====atoi()====]
[===strtol()===]
strtol() error: operand "123hello": Invalid argument