Last active
August 10, 2017 14:23
-
-
Save rbobillot/7db26cec3f5c78774a27acfb2ed1fb6c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
const int is_digit(const char c) { | |
return c >= '0' && c <= '9'; | |
} | |
const int is_space(const char c) { | |
return c >= 8 && c <= 32; | |
} | |
/* | |
** 'tr_' stands for 'tail recursive' | |
*/ | |
const int tr_pow(const int res, const int n, const int e) { | |
return e < 1 ? res : tr_pow(res * n, n, e - 1); | |
} | |
const char *tr_dropwhile(const char *s, const int (*predicate)(const char)) { | |
return s && predicate(*s) ? tr_dropwhile(s + 1, predicate) : s; | |
} | |
const int tr_count_while(const char *s, const char i, const int (*predicate)(const char)) { | |
return s && !predicate(*s) ? i : tr_count_while(s + 1, i + 1, predicate); | |
} | |
const int tr_compute(const int res, const char *num, const int dec) { | |
return num && !is_digit(*num) ? res : tr_compute(res + (*num - '0') * tr_pow(1, 10, dec), num + 1, dec - 1); | |
} | |
const int safe_atoi(const char *s) { | |
const char *str = str ? tr_dropwhile(s, &is_space) : s; | |
const int sign = (str && *str == '-') ? -1 : 1; | |
const char *num = (str && (sign == -1 || *str == '+')) ? ++str : str; | |
return !num ? 0 : sign * tr_compute(0, num, tr_count_while(num, 0, &is_digit) - 1); | |
} | |
////////////////////////////////////////////////// | |
// // | |
// TESTS // | |
// run with : gcc safe_atoi.c && ./a.out // | |
// // | |
////////////////////////////////////////////////// | |
int ft_atoi(const char *s) { | |
return (safe_atoi(s)); | |
} | |
int main(void) | |
{ | |
const char *values[] = { "", "0", "-0", "ft", "+2", "--2", "++2", "42", "-42", " 87654321", "-12345678", "12345678987654321", "-12345678987654321", "3.14", "42.ft", "42ft", "42 ft", "ft 42", 0 }; | |
int i = 0; | |
while (values[i]) { | |
const int n1 = ft_atoi(values[i]); | |
const int n2 = atoi(values[i]); | |
printf("%sft_atoi(\"%s\") = %d\n atoi(\"%s\") = %d\033[0m\n\n", (n1 == n2) ? "\033[92m" : "\033[91m", values[i], n1, values[i], n2); | |
++i; | |
} | |
// adding a check -> in case of NULL string (no segfault should occur) | |
ft_atoi(0); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment