Skip to content

Instantly share code, notes, and snippets.

@ikrabbe
Last active March 18, 2016 13:22
Show Gist options
  • Save ikrabbe/94df85203ace95542ba8 to your computer and use it in GitHub Desktop.
Save ikrabbe/94df85203ace95542ba8 to your computer and use it in GitHub Desktop.
A parse_float function with test
enum parseFloatErrorCodes {
SUCCESS, DOUBLE_DOT,PARSE_ERROR, INTEGER_OVERFLOW,
TOO_MANY_DIGITS_AFTER_DECIMAL_POINT
};
int parse_float(char* inp, float *x)
{
char *p;
int ival, dot;
for (ival = 0, dot = 0, p = inp; *p; ++p) {
int overflow_check = ival;
if (('0' <= *p) && (*p <= '9')) {
ival = ival * 10 + (int)(*p - '0');
if (dot > 0) ++dot;
} else if (*p == '.') {
if (dot > 0) { return DOUBLE_DOT; }
dot = 1;
} else { return PARSE_ERROR; }
if (overflow_check > ival) { return INTEGER_OVERFLOW; }
}
*x = ival;
if (dot == 0) *x *= 100.0;
else if (dot == 1) *x *= 100.0;
else if (dot == 2) *x *= 10.0;
else if (dot > 3) { return TOO_MANY_DIGITS_AFTER_DECIMAL_POINT; }
*x /= 100.0;
return SUCCESS;
}
#include <stdio.h>
#include <string.h>
void print_error(const char* buf, int code)
{
const char* str[] = {
"SUCCESS", "DOUBLE_DOT",
"PARSE_ERROR", "INTEGER_OVERFLOW",
"TOO_MANY_DIGITS_AFTER_DECIMAL_POINT"
};
if((SUCCESS <= code) && (code <= TOO_MANY_DIGITS_AFTER_DECIMAL_POINT)) {
printf("parse of \"%s\" failed with %s\n", buf, str[code]);
} else {
printf("unkown error code %d\n", code);
}
}
int main(int argc, char** argv)
{
const char *inp[] = {
"123",
"934.23",
"579346.24",
"1.5",
".2",
"3205986024967406709846.35",
"4535.23.13",
"SOMETHING ELSE",
"38575.23Numbers",
"123,54",
"0.123",
""
};
const char** I = inp;
char buf[40];
int len;
for (; strlen(*I) > 0; ++I) {
float x = .0f;
int errcode = SUCCESS;
len=strlen(*I);
if(len > 39) { printf("buffer overflow.\n"); return -1; }
memcpy(buf, *I, len);
buf[len] = '\0';
errcode = parse_float(buf, &x);
if (errcode == SUCCESS) {
printf("read float %5.2f\n", x);
} else {
print_error(buf, errcode);
}
}
return 0;
}
@ikrabbe
Copy link
Author

ikrabbe commented Mar 18, 2016

gcc -g -o parse_float parse_float.c
./parse_float
read float 123.00
read float 934.23
read float 579346.25
read float  1.50
read float  0.20
parse of "3205986024967406709846.35" failed with INTEGER_OVERFLOW
parse of "0.123" failed with TOO_MANY_DIGITS_AFTER_DECIMAL_POINT

@ikrabbe
Copy link
Author

ikrabbe commented Mar 18, 2016

More error codes triggered:

 ./parse_float
read float 123.00
read float 934.23
read float 579346.25
read float  1.50
read float  0.20
parse of "3205986024967406709846.35" failed with INTEGER_OVERFLOW
parse of "4535.23.13" failed with DOUBLE_DOT
parse of "SOMETHING ELSE" failed with PARSE_ERROR
parse of "38575.23Numbers" failed with PARSE_ERROR
parse of "123,54" failed with PARSE_ERROR
parse of "0.123" failed with TOO_MANY_DIGITS_AFTER_DECIMAL_POINT

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment