fork(1) download
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <stddef.h>
  4. #include <ctype.h>
  5. #include <string.h>
  6. #include <errno.h>
  7.  
  8.  
  9. /* Position exactly to integer beginning */
  10. /* e.g. if you have: "str-str-3str " */
  11. /* the returning pointer will point to: */
  12. /* "-3str". */
  13. const char* getNumberPos(const char* str)
  14. {
  15. const char* curChar = str;
  16. /* Iterate through part of integer is there. */
  17. while ( '\0' != curChar
  18. && !(isdigit(*curChar) || '+' == *curChar || '-' == *curChar))
  19. {
  20. ++curChar;
  21. }
  22. /* Check if the sign is part of an integer, */
  23. /* if not use this function recursive! */
  24. if ('+' == *curChar || '-' == *curChar)
  25. {
  26. const char* nextChar = curChar + 1;
  27. if ( '\0' != *nextChar
  28. && !isdigit(*nextChar))
  29. {
  30. ++curChar;
  31. curChar = getNumberPos(curChar);
  32. }
  33. }
  34. return curChar;
  35. }
  36.  
  37. /* Extended strtol function */
  38. long my_strtol(const char* str, char** endptr, int base)
  39. {
  40. const char* curChar = getNumberPos(str);
  41. return strtol(curChar, endptr, base);
  42. }
  43.  
  44.  
  45. int main()
  46. {
  47. /* Loop index */
  48. int idx;
  49.  
  50. /* Declare and initialize char arrays. */
  51. char array[] = { "3" };
  52. char arrayI[] = { " 3 " };
  53. char arrayII[] = { " -3 " };
  54. char arrayIII[] = { "str 3 " };
  55. char arrayIV[] = { "str-3 " };
  56. char arrayV[] = { " 3str" };
  57. char arrayVI[] = { " -3str" };
  58. char arrayVII[] = { "str-3str" };
  59. char arrayVIII[] = { "s-r-3str" };
  60.  
  61. /* Save each array in one array for iteration purposes. */
  62. const char* const arrays[] = { array,
  63. arrayI,
  64. arrayII,
  65. arrayIII,
  66. arrayIV,
  67. arrayV,
  68. arrayVI,
  69. arrayVII,
  70. arrayVIII };
  71. /* Get size of that array. */
  72. const int arraysSize = sizeof(arrays) / sizeof(char*);
  73.  
  74. /* atoi(): Does not detect errors! */
  75. for (idx = 0; idx < arraysSize; ++idx)
  76. {
  77. int integer = atoi(arrays[idx]);
  78.  
  79. printf("%d: atoi with \"%s\" %*s to integer: %+d\n",
  80. idx,
  81. arrays[idx],
  82. 8 - strlen (arrays[idx]),
  83. "",
  84. integer);
  85. }
  86. printf("\n");
  87.  
  88. /* sscanf(): Error detection by using the matched item count. */
  89. for (idx = 0; idx < arraysSize; ++idx)
  90. {
  91. int integer = 0;
  92. int itemCount = sscanf(arrays[idx], "%d", &integer);
  93.  
  94. printf("%d: sscanf with \"%s\" %*s to integer: %+d | itemCount = %d",
  95. idx,
  96. arrays[idx],
  97. 8 - strlen (arrays[idx]),
  98. "",
  99. integer,
  100. itemCount);
  101.  
  102. if (0 == itemCount)
  103. {
  104. printf(" --> Error!");
  105. }
  106. printf("\n");
  107. }
  108. printf("\n");
  109.  
  110. /* strtol(): Error detection by using errno and returned end pointer. */
  111. for (idx = 0; idx < arraysSize; ++idx)
  112. {
  113. char* endPtr = NULL;
  114. ptrdiff_t ptrDiff = 0;
  115. errno = 0;
  116. /* You have to check if the long can be stored in the int, not done here! */
  117. int integer = (int) strtol(arrays[idx], &endPtr, 10);
  118. ptrDiff = endPtr - arrays[idx];
  119.  
  120. printf("%d: strtol with \"%s\" %*s to integer: %+d | errno = %d, StartPtr = %p, EndPtr = %p, PtrDiff = %ld",
  121. idx,
  122. arrays[idx],
  123. 8 - strlen (arrays[idx]),
  124. "",
  125. integer,
  126. errno,
  127. (void*) arrays[idx],
  128. (void*) endPtr,
  129. ptrDiff);
  130.  
  131. if (0 != errno || 0 == ptrDiff)
  132. {
  133. printf(" --> Error!");
  134. }
  135. printf("\n");
  136. }
  137. printf("\n");
  138.  
  139. /* my_strtol: Same as strtol here. */
  140. for (idx = 0; idx < arraysSize; ++idx)
  141. {
  142. char* endPtr = NULL;
  143. ptrdiff_t ptrDiff = 0;
  144. errno = 0;
  145. /* You have to check if the long can be stored in the int, not done here! */
  146. int integer = (int) my_strtol(arrays[idx], &endPtr, 10);
  147. ptrDiff = endPtr - arrays[idx];
  148.  
  149. printf("%d: my_strtol with \"%s\" %*s to integer: %+d | errno = %d, StartPtr = %p, EndPtr = %p, PtrDiff = %ld",
  150. idx,
  151. arrays[idx],
  152. 8 - strlen (arrays[idx]),
  153. "",
  154. integer,
  155. errno,
  156. (void*) arrays[idx],
  157. (void*) endPtr,
  158. ptrDiff);
  159.  
  160. if (0 != errno || 0 == ptrDiff)
  161. {
  162. printf(" --> Error!");
  163. }
  164. printf("\n");
  165. }
  166.  
  167. return 0;
  168. }
Success #stdin #stdout 0s 9432KB
stdin
Standard input is empty
stdout
0: atoi with "3"         to integer: +3
1: atoi with "    3   "  to integer: +3
2: atoi with "   -3   "  to integer: -3
3: atoi with "str 3   "  to integer: +0
4: atoi with "str-3   "  to integer: +0
5: atoi with "    3str"  to integer: +3
6: atoi with "   -3str"  to integer: -3
7: atoi with "str-3str"  to integer: +0
8: atoi with "s-r-3str"  to integer: +0

0: sscanf with "3"         to integer: +3 | itemCount = 1
1: sscanf with "    3   "  to integer: +3 | itemCount = 1
2: sscanf with "   -3   "  to integer: -3 | itemCount = 1
3: sscanf with "str 3   "  to integer: +0 | itemCount = 0 --> Error!
4: sscanf with "str-3   "  to integer: +0 | itemCount = 0 --> Error!
5: sscanf with "    3str"  to integer: +3 | itemCount = 1
6: sscanf with "   -3str"  to integer: -3 | itemCount = 1
7: sscanf with "str-3str"  to integer: +0 | itemCount = 0 --> Error!
8: sscanf with "s-r-3str"  to integer: +0 | itemCount = 0 --> Error!

0: strtol with "3"         to integer: +3 | errno =  0, StartPtr = 0x7ffc321c01b0, EndPtr = 0x7ffc321c01b1, PtrDiff = 1
1: strtol with "    3   "  to integer: +3 | errno =  0, StartPtr = 0x7ffc321c01c0, EndPtr = 0x7ffc321c01c5, PtrDiff = 5
2: strtol with "   -3   "  to integer: -3 | errno =  0, StartPtr = 0x7ffc321c01d0, EndPtr = 0x7ffc321c01d5, PtrDiff = 5
3: strtol with "str 3   "  to integer: +0 | errno =  0, StartPtr = 0x7ffc321c01e0, EndPtr = 0x7ffc321c01e0, PtrDiff = 0 --> Error!
4: strtol with "str-3   "  to integer: +0 | errno =  0, StartPtr = 0x7ffc321c01f0, EndPtr = 0x7ffc321c01f0, PtrDiff = 0 --> Error!
5: strtol with "    3str"  to integer: +3 | errno =  0, StartPtr = 0x7ffc321c0200, EndPtr = 0x7ffc321c0205, PtrDiff = 5
6: strtol with "   -3str"  to integer: -3 | errno =  0, StartPtr = 0x7ffc321c0210, EndPtr = 0x7ffc321c0215, PtrDiff = 5
7: strtol with "str-3str"  to integer: +0 | errno =  0, StartPtr = 0x7ffc321c0220, EndPtr = 0x7ffc321c0220, PtrDiff = 0 --> Error!
8: strtol with "s-r-3str"  to integer: +0 | errno =  0, StartPtr = 0x7ffc321c0230, EndPtr = 0x7ffc321c0230, PtrDiff = 0 --> Error!

0: my_strtol with "3"         to integer: +3 | errno =  0, StartPtr = 0x7ffc321c01b0, EndPtr = 0x7ffc321c01b1, PtrDiff = 1
1: my_strtol with "    3   "  to integer: +3 | errno =  0, StartPtr = 0x7ffc321c01c0, EndPtr = 0x7ffc321c01c5, PtrDiff = 5
2: my_strtol with "   -3   "  to integer: -3 | errno =  0, StartPtr = 0x7ffc321c01d0, EndPtr = 0x7ffc321c01d5, PtrDiff = 5
3: my_strtol with "str 3   "  to integer: +3 | errno =  0, StartPtr = 0x7ffc321c01e0, EndPtr = 0x7ffc321c01e5, PtrDiff = 5
4: my_strtol with "str-3   "  to integer: -3 | errno =  0, StartPtr = 0x7ffc321c01f0, EndPtr = 0x7ffc321c01f5, PtrDiff = 5
5: my_strtol with "    3str"  to integer: +3 | errno =  0, StartPtr = 0x7ffc321c0200, EndPtr = 0x7ffc321c0205, PtrDiff = 5
6: my_strtol with "   -3str"  to integer: -3 | errno =  0, StartPtr = 0x7ffc321c0210, EndPtr = 0x7ffc321c0215, PtrDiff = 5
7: my_strtol with "str-3str"  to integer: -3 | errno =  0, StartPtr = 0x7ffc321c0220, EndPtr = 0x7ffc321c0225, PtrDiff = 5
8: my_strtol with "s-r-3str"  to integer: -3 | errno =  0, StartPtr = 0x7ffc321c0230, EndPtr = 0x7ffc321c0235, PtrDiff = 5