Bug:
int_to_str()fails for negativeint.Undefined specifiers:
%hand%Hare not part of the standard library. So without a specification, hard to know if they are performing correctly. Did you mean%xand%X?Mixing
intandsize_tmath. This is pedantic point. As the max of those 2 types are not specified to which is larger, there is a worst case chancemax_size - chars_printed <= 0will never be true shouldmax_size > INT_MAX. Suggest adding the**line below and avoid math that relies on signed math as it is likely unsigned math. or usesize_t chars_printedand cope with returningintat the end. (chars_printedshould be of the type with the greater positive range.)int my_snprintf(char *str, size_t max_size, const char *fmt, ...) { if (max_size > INT_MAX) Handle_PathologicalCase_TBD(); // ** int chars_printed = 0; ... // if (max_size - chars_printed <= 0) { if (max_size <= chars_printed) {Bug
int length = (int)ceil(log((double)x)/log((double)base));is not as reliable as hoped for. Detailed well in another answeranswer. The alternative is to convert to a string with an internal max-sized buffer likechar buf[34]forint32_tin base 2. Then copy the buffer result.Style: fall through. Cases that drop though look like an error without a
break. Add comment to show intentcase 'H': uppercase = 1; // fall though case 'h': base = 16; // fall though case 'd':printf("Invalid format.\n");and such are better printed tostderr.fprintf(stderr, "Invalid format.\n");Wrong type for
len// int len; size_t len;Style: No need to declare
dso soon. Same forc. Suggest type changeunsigned char c = va_arg(arg_list, int);. Same forstr_arg.// int num; // ... ~30 lines // case 'd': // num = va_arg(arg_list, int); case 'd': int num = va_arg(arg_list, int);Minor: Code simplification
// if (uppercase) { // c = INT_TO_STR_DIGITS_U[r]; // ... if (uppercase) { c = "0123456789ABCDEF"[r]; } else { c = "0123456789abcdef"[r]; }Corner bug: Below code fails (UB). Watch for
size == 0my_snprintf(str, 0, fmt, ...)[Edit] Bug:
int uppercase = 0, base = 10;is initialized outside thefor()loop. So a"%d"after a"%x"will be treated as hex. A"%h"after a"%H"will be treated as print with uppercase letters. Simple fix, moveint uppercase = 0, base = 10;to afterelse if (fmt[i] == '%'). Better fix: pass base and upper/lower as parameters to newint_to_str().char *start_strunused. Recommend deletion.Variables/functions like
INT_TO_STR_DIGITS_L[]andint_to_str()that are only intended for local use should bestatic. Unclear why all uppercase. Avoid long line that exceed presentation width// int INT_TO_STR_DIGITS_L[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
replaced http://codereview.stackexchange.com/ with https://codereview.stackexchange.com/