I'm trying to parse a char*
into an int
without using atoi()
. I walk through the string, check if it's a valid digit, then add that digit to my integer by multiplying by 10 and adding the digit. I am not accepting negative integers.
Here's the code I'm using:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define TRUE 1
#define FALSE 0
int main(int argc, char *argv[]) {
if (argc < 2)
exit(1);
char *p = argv[1];
int amount = 0;
int len = strlen((const char*) argv[1]); // calculate len beforehand
int contin = TRUE;
for (int i = 0; contin && i < len; ++i, ++p) {
switch (*p) {
case '0':
amount = (amount * 10);
break;
case '1':
amount = (amount * 10) + 1;
break;
case '2':
amount = (amount * 10) + 2;
break;
case '3':
amount = (amount * 10) + 3;
break;
case '4':
amount = (amount * 10) + 4;
break;
case '5':
amount = (amount * 10) + 5;
break;
case '6':
amount = (amount * 10) + 6;
break;
case '7':
amount = (amount * 10) + 7;
break;
case '8':
amount = (amount * 10) + 8;
break;
case '9':
amount = (amount * 10) + 9;
break;
default:
contin = FALSE;
break;
}
}
fprintf(stdout, "amount: %i\n", amount);
return 0;
}
...which works nicely. But, is there a better/more idiomatic way to do this?
EDIT: Thanks to Groo, I'm able to remove the giant switch statement:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define TRUE 1
#define FALSE 0
int main(int argc, char *argv[]) {
if (argc < 2)
exit(1);
char *p = argv[1];
int amount = 0;
int len = strlen((const char*) argv[1]); // calculate len beforehand
int contin = TRUE;
for (int i = 0; contin && i < len; ++i, ++p) {
/* handle negative integers */
if (*p == '-' && i == 0) {
fprintf(stderr, "negative integers are invalid.\n");
exit(1);
}
if (*p > 0x2F && *p < 0x3A)
amount = (amount * 10) + (*p - '0');
else {
contin = FALSE;
--p;
}
}
fprintf(stdout, "amount: %i\n", amount);
return 0;
}
```
0x2F
and0x3A
because most people don't know ASCII by heart and because your intent is to compare then with the digits zero and nine. Use'0'
and'9'
-- it's easier to understand and better reflects the intent of the code. \$\endgroup\$ – David Schwartz Jan 19 '20 at 7:44