Skip to content

Instantly share code, notes, and snippets.

@rbobillot
Last active August 10, 2017 14:23
Show Gist options
  • Save rbobillot/7db26cec3f5c78774a27acfb2ed1fb6c to your computer and use it in GitHub Desktop.
Save rbobillot/7db26cec3f5c78774a27acfb2ed1fb6c to your computer and use it in GitHub Desktop.
#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