#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <ctype.h>
#include <string.h>
#include <errno.h>
/* Position exactly to integer beginning */
/* e.g. if you have: "str-str-3str " */
/* the returning pointer will point to: */
/* "-3str". */
const char* getNumberPos(const char* str)
{
const char* curChar = str;
/* Iterate through part of integer is there. */
while ( '\0' != curChar
&& !(isdigit(*curChar
) || '+' == *curChar
|| '-' == *curChar
)) {
++curChar;
}
/* Check if the sign is part of an integer, */
/* if not use this function recursive! */
if ('+' == *curChar || '-' == *curChar)
{
const char* nextChar = curChar + 1;
if ( '\0' != *nextChar
{
++curChar;
curChar = getNumberPos(curChar);
}
}
return curChar;
}
/* Extended strtol function */
long my_strtol(const char* str, char** endptr, int base)
{
const char* curChar = getNumberPos(str);
return strtol(curChar
, endptr
, base
); }
int main()
{
/* Loop index */
int idx;
/* Declare and initialize char arrays. */
char array[] = { "3" };
char arrayI[] = { " 3 " };
char arrayII[] = { " -3 " };
char arrayIII[] = { "str 3 " };
char arrayIV[] = { "str-3 " };
char arrayV[] = { " 3str" };
char arrayVI[] = { " -3str" };
char arrayVII[] = { "str-3str" };
char arrayVIII[] = { "s-r-3str" };
/* Save each array in one array for iteration purposes. */
const char* const arrays[] = { array,
arrayI,
arrayII,
arrayIII,
arrayIV,
arrayV,
arrayVI,
arrayVII,
arrayVIII };
/* Get size of that array. */
const int arraysSize = sizeof(arrays) / sizeof(char*);
/* atoi(): Does not detect errors! */
for (idx = 0; idx < arraysSize; ++idx)
{
int integer
= atoi(arrays
[idx
]);
printf("%d: atoi with \"%s\" %*s to integer: %+d\n", idx,
arrays[idx],
"",
integer);
}
/* sscanf(): Error detection by using the matched item count. */
for (idx = 0; idx < arraysSize; ++idx)
{
int integer = 0;
int itemCount
= sscanf(arrays
[idx
], "%d", &integer
);
printf("%d: sscanf with \"%s\" %*s to integer: %+d | itemCount = %d", idx,
arrays[idx],
"",
integer,
itemCount);
if (0 == itemCount)
{
}
}
/* strtol(): Error detection by using errno and returned end pointer. */
for (idx = 0; idx < arraysSize; ++idx)
{
char* endPtr = NULL;
ptrdiff_t ptrDiff = 0;
errno = 0;
/* You have to check if the long can be stored in the int, not done here! */
int integer
= (int) strtol(arrays
[idx
], &endPtr
, 10); ptrDiff = endPtr - arrays[idx];
printf("%d: strtol with \"%s\" %*s to integer: %+d | errno = %d, StartPtr = %p, EndPtr = %p, PtrDiff = %ld", idx,
arrays[idx],
"",
integer,
errno,
(void*) arrays[idx],
(void*) endPtr,
ptrDiff);
if (0 != errno || 0 == ptrDiff)
{
}
}
/* my_strtol: Same as strtol here. */
for (idx = 0; idx < arraysSize; ++idx)
{
char* endPtr = NULL;
ptrdiff_t ptrDiff = 0;
errno = 0;
/* You have to check if the long can be stored in the int, not done here! */
int integer = (int) my_strtol(arrays[idx], &endPtr, 10);
ptrDiff = endPtr - arrays[idx];
printf("%d: my_strtol with \"%s\" %*s to integer: %+d | errno = %d, StartPtr = %p, EndPtr = %p, PtrDiff = %ld", idx,
arrays[idx],
"",
integer,
errno,
(void*) arrays[idx],
(void*) endPtr,
ptrDiff);
if (0 != errno || 0 == ptrDiff)
{
}
}
return 0;
}
I2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPHN0ZGRlZi5oPgojaW5jbHVkZSA8Y3R5cGUuaD4KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8ZXJybm8uaD4KCgovKiBQb3NpdGlvbiBleGFjdGx5IHRvIGludGVnZXIgYmVnaW5uaW5nICovCi8qIGUuZy4gaWYgeW91IGhhdmU6ICJzdHItc3RyLTNzdHIgIiAgICAgKi8KLyogdGhlIHJldHVybmluZyBwb2ludGVyIHdpbGwgcG9pbnQgdG86ICAqLwovKiAiLTNzdHIiLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCmNvbnN0IGNoYXIqIGdldE51bWJlclBvcyhjb25zdCBjaGFyKiBzdHIpCnsKICAgY29uc3QgY2hhciogY3VyQ2hhciA9IHN0cjsKICAgLyogSXRlcmF0ZSB0aHJvdWdoIHBhcnQgb2YgaW50ZWdlciBpcyB0aGVyZS4gKi8KICAgd2hpbGUgKCAgICdcMCcgIT0gY3VyQ2hhcgogICAgICAgICAgJiYgIShpc2RpZ2l0KCpjdXJDaGFyKSB8fCAnKycgPT0gKmN1ckNoYXIgfHwgJy0nID09ICpjdXJDaGFyKSkKICAgewogICAgICArK2N1ckNoYXI7CiAgIH0KICAgLyogQ2hlY2sgaWYgdGhlIHNpZ24gaXMgcGFydCBvZiBhbiBpbnRlZ2VyLCAqLwogICAvKiBpZiBub3QgdXNlIHRoaXMgZnVuY3Rpb24gcmVjdXJzaXZlISAgICAgICovCiAgIGlmICgnKycgPT0gKmN1ckNoYXIgfHwgJy0nID09ICpjdXJDaGFyKQogICB7CiAgICAgIGNvbnN0IGNoYXIqIG5leHRDaGFyID0gY3VyQ2hhciArIDE7CiAgICAgIGlmICggICAnXDAnICE9ICpuZXh0Q2hhcgogICAgICAgICAgJiYgIWlzZGlnaXQoKm5leHRDaGFyKSkKICAgICAgewogICAgICAgICArK2N1ckNoYXI7CiAgICAgICAgIGN1ckNoYXIgPSBnZXROdW1iZXJQb3MoY3VyQ2hhcik7CiAgICAgIH0KICAgfQogICByZXR1cm4gY3VyQ2hhcjsKfQoKLyogRXh0ZW5kZWQgc3RydG9sIGZ1bmN0aW9uICovCmxvbmcgbXlfc3RydG9sKGNvbnN0IGNoYXIqIHN0ciwgY2hhcioqIGVuZHB0ciwgaW50IGJhc2UpCnsKICAgY29uc3QgY2hhciogY3VyQ2hhciA9IGdldE51bWJlclBvcyhzdHIpOwogICByZXR1cm4gc3RydG9sKGN1ckNoYXIsIGVuZHB0ciwgYmFzZSk7Cn0KCgppbnQgbWFpbigpCnsKICAgLyogTG9vcCBpbmRleCAqLwogICBpbnQgaWR4OwoKICAgLyogRGVjbGFyZSBhbmQgaW5pdGlhbGl6ZSBjaGFyIGFycmF5cy4gKi8KICAgY2hhciBhcnJheVtdICAgICAgPSB7ICIzIiB9OwogICBjaGFyIGFycmF5SVtdICAgICA9IHsgIiAgICAzICAgIiB9OwogICBjaGFyIGFycmF5SUlbXSAgICA9IHsgIiAgIC0zICAgIiB9OwogICBjaGFyIGFycmF5SUlJW10gICA9IHsgInN0ciAzICAgIiB9OwogICBjaGFyIGFycmF5SVZbXSAgICA9IHsgInN0ci0zICAgIiB9OwogICBjaGFyIGFycmF5VltdICAgICA9IHsgIiAgICAzc3RyIiB9OwogICBjaGFyIGFycmF5VklbXSAgICA9IHsgIiAgIC0zc3RyIiB9OwogICBjaGFyIGFycmF5VklJW10gICA9IHsgInN0ci0zc3RyIiB9OwogICBjaGFyIGFycmF5VklJSVtdICA9IHsgInMtci0zc3RyIiB9OwoKICAgLyogU2F2ZSBlYWNoIGFycmF5IGluIG9uZSBhcnJheSBmb3IgaXRlcmF0aW9uIHB1cnBvc2VzLiAqLwogICBjb25zdCBjaGFyKiBjb25zdCBhcnJheXNbXSA9IHsgYXJyYXksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcnJheUksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcnJheUlJLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJyYXlJSUksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcnJheUlWLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJyYXlWLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJyYXlWSSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFycmF5VklJLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJyYXlWSUlJIH07CiAgIC8qIEdldCBzaXplIG9mIHRoYXQgYXJyYXkuICovCiAgIGNvbnN0IGludCBhcnJheXNTaXplID0gc2l6ZW9mKGFycmF5cykgLyBzaXplb2YoY2hhciopOwoKICAgLyogYXRvaSgpOiBEb2VzIG5vdCBkZXRlY3QgZXJyb3JzISAqLwogICBmb3IgKGlkeCA9IDA7IGlkeCA8IGFycmF5c1NpemU7ICsraWR4KQogICB7CiAgICAgIGludCBpbnRlZ2VyID0gYXRvaShhcnJheXNbaWR4XSk7CgogICAgICBwcmludGYoIiVkOiBhdG9pIHdpdGggXCIlc1wiICUqcyB0byBpbnRlZ2VyOiAlK2RcbiIsCiAgICAgICAgICAgICBpZHgsCiAgICAgICAgICAgICBhcnJheXNbaWR4XSwKICAgICAgICAgICAgIDggLSBzdHJsZW4gKGFycmF5c1tpZHhdKSwKICAgICAgICAgICAgICIiLAogICAgICAgICAgICAgaW50ZWdlcik7CiAgIH0KICAgcHJpbnRmKCJcbiIpOwoKICAgLyogc3NjYW5mKCk6IEVycm9yIGRldGVjdGlvbiBieSB1c2luZyB0aGUgbWF0Y2hlZCBpdGVtIGNvdW50LiAqLwogICBmb3IgKGlkeCA9IDA7IGlkeCA8IGFycmF5c1NpemU7ICsraWR4KQogICB7CiAgICAgIGludCBpbnRlZ2VyID0gMDsKICAgICAgaW50IGl0ZW1Db3VudCA9IHNzY2FuZihhcnJheXNbaWR4XSwgIiVkIiwgJmludGVnZXIpOwoKICAgICAgcHJpbnRmKCIlZDogc3NjYW5mIHdpdGggXCIlc1wiICUqcyB0byBpbnRlZ2VyOiAlK2QgfCBpdGVtQ291bnQgPSAlZCIsCiAgICAgICAgICAgICBpZHgsCiAgICAgICAgICAgICBhcnJheXNbaWR4XSwKICAgICAgICAgICAgIDggLSBzdHJsZW4gKGFycmF5c1tpZHhdKSwKICAgICAgICAgICAgICIiLAogICAgICAgICAgICAgaW50ZWdlciwKICAgICAgICAgICAgIGl0ZW1Db3VudCk7CgogICAgICBpZiAoMCA9PSBpdGVtQ291bnQpCiAgICAgIHsKICAgICAgICAgcHJpbnRmKCIgLS0+IEVycm9yISIpOwogICAgICB9CiAgICAgIHByaW50ZigiXG4iKTsKICAgfQogICBwcmludGYoIlxuIik7CgogICAvKiBzdHJ0b2woKTogRXJyb3IgZGV0ZWN0aW9uIGJ5IHVzaW5nIGVycm5vIGFuZCByZXR1cm5lZCBlbmQgcG9pbnRlci4gKi8KICAgZm9yIChpZHggPSAwOyBpZHggPCBhcnJheXNTaXplOyArK2lkeCkKICAgewogICAgICBjaGFyKiAgICAgZW5kUHRyICA9IE5VTEw7CiAgICAgIHB0cmRpZmZfdCBwdHJEaWZmID0gMDsKICAgICAgZXJybm8gICAgICAgICAgICAgPSAwOwogICAgICAvKiBZb3UgaGF2ZSB0byBjaGVjayBpZiB0aGUgbG9uZyBjYW4gYmUgc3RvcmVkIGluIHRoZSBpbnQsIG5vdCBkb25lIGhlcmUhICovCiAgICAgIGludCBpbnRlZ2VyID0gKGludCkgc3RydG9sKGFycmF5c1tpZHhdLCAmZW5kUHRyLCAxMCk7CiAgICAgIHB0ckRpZmYgPSBlbmRQdHIgLSBhcnJheXNbaWR4XTsKCiAgICAgIHByaW50ZigiJWQ6IHN0cnRvbCB3aXRoIFwiJXNcIiAlKnMgdG8gaW50ZWdlcjogJStkIHwgZXJybm8gPSAgJWQsIFN0YXJ0UHRyID0gJXAsIEVuZFB0ciA9ICVwLCBQdHJEaWZmID0gJWxkIiwKICAgICAgICAgICAgIGlkeCwKICAgICAgICAgICAgIGFycmF5c1tpZHhdLAogICAgICAgICAgICAgOCAtIHN0cmxlbiAoYXJyYXlzW2lkeF0pLAogICAgICAgICAgICAgIiIsCiAgICAgICAgICAgICBpbnRlZ2VyLAogICAgICAgICAgICAgZXJybm8sCiAgICAgICAgICAgICAodm9pZCopIGFycmF5c1tpZHhdLAogICAgICAgICAgICAgKHZvaWQqKSBlbmRQdHIsCiAgICAgICAgICAgICBwdHJEaWZmKTsKCiAgICAgIGlmICgwICE9IGVycm5vIHx8IDAgPT0gcHRyRGlmZikKICAgICAgewogICAgICAgICBwcmludGYoIiAtLT4gRXJyb3IhIik7CiAgICAgIH0KICAgICAgcHJpbnRmKCJcbiIpOwogICB9CiAgIHByaW50ZigiXG4iKTsKCiAgIC8qIG15X3N0cnRvbDogU2FtZSBhcyBzdHJ0b2wgaGVyZS4gKi8KICAgZm9yIChpZHggPSAwOyBpZHggPCBhcnJheXNTaXplOyArK2lkeCkKICAgewogICAgICBjaGFyKiAgICAgZW5kUHRyICA9IE5VTEw7CiAgICAgIHB0cmRpZmZfdCBwdHJEaWZmID0gMDsKICAgICAgZXJybm8gICAgICAgICAgICAgPSAwOwogICAgICAvKiBZb3UgaGF2ZSB0byBjaGVjayBpZiB0aGUgbG9uZyBjYW4gYmUgc3RvcmVkIGluIHRoZSBpbnQsIG5vdCBkb25lIGhlcmUhICovCiAgICAgIGludCBpbnRlZ2VyID0gKGludCkgbXlfc3RydG9sKGFycmF5c1tpZHhdLCAmZW5kUHRyLCAxMCk7CiAgICAgIHB0ckRpZmYgPSBlbmRQdHIgLSBhcnJheXNbaWR4XTsKCiAgICAgIHByaW50ZigiJWQ6IG15X3N0cnRvbCB3aXRoIFwiJXNcIiAlKnMgdG8gaW50ZWdlcjogJStkIHwgZXJybm8gPSAgJWQsIFN0YXJ0UHRyID0gJXAsIEVuZFB0ciA9ICVwLCBQdHJEaWZmID0gJWxkIiwKICAgICAgICAgICAgIGlkeCwKICAgICAgICAgICAgIGFycmF5c1tpZHhdLAogICAgICAgICAgICAgOCAtIHN0cmxlbiAoYXJyYXlzW2lkeF0pLAogICAgICAgICAgICAgIiIsCiAgICAgICAgICAgICBpbnRlZ2VyLAogICAgICAgICAgICAgZXJybm8sCiAgICAgICAgICAgICAodm9pZCopIGFycmF5c1tpZHhdLAogICAgICAgICAgICAgKHZvaWQqKSBlbmRQdHIsCiAgICAgICAgICAgICBwdHJEaWZmKTsKCiAgICAgIGlmICgwICE9IGVycm5vIHx8IDAgPT0gcHRyRGlmZikKICAgICAgewogICAgICAgICBwcmludGYoIiAtLT4gRXJyb3IhIik7CiAgICAgIH0KICAgICAgcHJpbnRmKCJcbiIpOwogICB9CgogICByZXR1cm4gMDsKfQ==
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