| Directory: | ./ |
|---|---|
| File: | s21_sprintf_converters.c |
| Date: | 2025-11-01 23:04:41 |
| Exec | Total | Coverage | |
|---|---|---|---|
| Lines: | 108 | 110 | 98.2% |
| Branches: | 57 | 60 | 95.0% |
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #include <locale.h> | ||
| 2 | #include <math.h> | ||
| 3 | #include <stdlib.h> | ||
| 4 | |||
| 5 | #include "s21_sprintf.h" | ||
| 6 | |||
| 7 | 42 | void char_to_str(int num, char *str) { | |
| 8 | 42 | *(str++) = (char)num; | |
| 9 | 42 | *str = '\0'; | |
| 10 | 42 | } | |
| 11 | |||
| 12 | 11 | void wchar_to_str(wchar_t wc, char *str) { | |
| 13 | 11 | setlocale(LC_ALL, ""); | |
| 14 | char wc_str[8]; | ||
| 15 | 11 | int len = wctomb(wc_str, wc); | |
| 16 |
1/2✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
|
11 | if (len >= 0) { |
| 17 | 11 | s21_memcpy(str, wc_str, len); | |
| 18 | 11 | str[len] = '\0'; | |
| 19 | } else { | ||
| 20 | ✗ | str[0] = '\0'; | |
| 21 | } | ||
| 22 | 11 | } | |
| 23 | |||
| 24 | 1976 | void int_to_str(long long num, char *str, const FormatSpecifier *fs) { | |
| 25 | 1976 | int len = 0; | |
| 26 |
4/4✓ Branch 0 taken 4 times.
✓ Branch 1 taken 1972 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 1 times.
|
1976 | if (!(num == 0 && fs->precision == 0)) { |
| 27 | 1975 | int is_negative = 0; | |
| 28 |
2/2✓ Branch 0 taken 1037 times.
✓ Branch 1 taken 938 times.
|
1975 | if (num < 0) { |
| 29 | 1037 | is_negative = 1; | |
| 30 | 1037 | num = -num; | |
| 31 | } | ||
| 32 | do { | ||
| 33 | 5844 | str[len++] = num % 10 + '0'; | |
| 34 | 5844 | num /= 10; | |
| 35 |
2/2✓ Branch 0 taken 3869 times.
✓ Branch 1 taken 1975 times.
|
5844 | } while (num); |
| 36 |
2/2✓ Branch 0 taken 36 times.
✓ Branch 1 taken 1975 times.
|
2011 | while (len < fs->precision) { |
| 37 | 36 | str[len++] = '0'; | |
| 38 | } | ||
| 39 |
2/2✓ Branch 0 taken 1037 times.
✓ Branch 1 taken 938 times.
|
1975 | if (is_negative) { |
| 40 | 1037 | str[len++] = '-'; | |
| 41 |
2/2✓ Branch 0 taken 29 times.
✓ Branch 1 taken 909 times.
|
938 | } else if (fs->show_sign) { |
| 42 | 29 | str[len++] = '+'; | |
| 43 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 907 times.
|
909 | } else if (fs->space_for_positive) { |
| 44 | 2 | str[len++] = ' '; | |
| 45 | } | ||
| 46 |
2/2✓ Branch 0 taken 2974 times.
✓ Branch 1 taken 1975 times.
|
4949 | for (int i = 0; i < len / 2; i++) { |
| 47 | 2974 | char tmp = str[i]; | |
| 48 | 2974 | str[i] = str[len - 1 - i]; | |
| 49 | 2974 | str[len - 1 - i] = tmp; | |
| 50 | } | ||
| 51 | } | ||
| 52 | 1976 | str[len] = '\0'; | |
| 53 | 1976 | } | |
| 54 | |||
| 55 | 86 | void uint_to_str(unsigned long num, char *str, const FormatSpecifier *fs) { | |
| 56 | 86 | int len = 0; | |
| 57 |
4/4✓ Branch 0 taken 7 times.
✓ Branch 1 taken 79 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 1 times.
|
86 | if (!(num == 0 && fs->precision == 0)) { |
| 58 | do { | ||
| 59 | 201 | str[len++] = num % 10 + '0'; | |
| 60 | 201 | num /= 10; | |
| 61 |
2/2✓ Branch 0 taken 116 times.
✓ Branch 1 taken 85 times.
|
201 | } while (num); |
| 62 |
2/2✓ Branch 0 taken 39 times.
✓ Branch 1 taken 85 times.
|
124 | while (len < fs->precision) { |
| 63 | 39 | str[len++] = '0'; | |
| 64 | } | ||
| 65 |
2/2✓ Branch 0 taken 82 times.
✓ Branch 1 taken 85 times.
|
167 | for (int i = 0; i < len / 2; i++) { |
| 66 | 82 | char tmp = str[i]; | |
| 67 | 82 | str[i] = str[len - 1 - i]; | |
| 68 | 82 | str[len - 1 - i] = tmp; | |
| 69 | } | ||
| 70 | } | ||
| 71 | 86 | str[len] = '\0'; | |
| 72 | 86 | } | |
| 73 | |||
| 74 | 72 | void float_to_str(long double num, char *str, FormatSpecifier *fs) { | |
| 75 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 71 times.
|
72 | if (isnan(num)) { |
| 76 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | if (signbit(num)) { |
| 77 | ✗ | s21_strncpy(str, "-nan", 5); | |
| 78 | } else { | ||
| 79 | 1 | s21_strncpy(str, "nan", 4); | |
| 80 | } | ||
| 81 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 69 times.
|
71 | } else if (isinf(num)) { |
| 82 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
|
2 | if (num < 0) { |
| 83 | 1 | s21_strncpy(str, "-inf", 5); | |
| 84 | } else { | ||
| 85 | 1 | s21_strncpy(str, "inf", 4); | |
| 86 | } | ||
| 87 | } else { | ||
| 88 | 69 | convert_to_float(num, str, fs); | |
| 89 | } | ||
| 90 | 72 | } | |
| 91 | |||
| 92 | 69 | void convert_to_float(long double num, char *str, FormatSpecifier *fs) { | |
| 93 | 69 | int len = 0; | |
| 94 | 69 | int is_negative = 0; | |
| 95 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 68 times.
|
69 | if (num < 0) { |
| 96 | 1 | is_negative = 1; | |
| 97 | 1 | num = -num; | |
| 98 | } | ||
| 99 |
2/2✓ Branch 0 taken 10 times.
✓ Branch 1 taken 59 times.
|
69 | if (fs->precision == -1) { |
| 100 | 10 | fs->precision = 6; | |
| 101 | } | ||
| 102 | 69 | double factor = pow(10.0, fs->precision); | |
| 103 | 69 | num = round(num * factor) / factor; | |
| 104 | 69 | s21_size_t int_part = (s21_size_t)num; | |
| 105 | 69 | long double frac_part = num - (long double)int_part; | |
| 106 | char int_buf[64]; | ||
| 107 | 69 | int precision = fs->precision; | |
| 108 | 69 | fs->precision = -1; | |
| 109 | 69 | uint_to_str(int_part, int_buf, fs); | |
| 110 | 69 | fs->precision = precision; | |
| 111 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 68 times.
|
69 | if (is_negative) { |
| 112 | 1 | str[len++] = '-'; | |
| 113 |
2/2✓ Branch 0 taken 9 times.
✓ Branch 1 taken 59 times.
|
68 | } else if (fs->show_sign) { |
| 114 | 9 | str[len++] = '+'; | |
| 115 |
2/2✓ Branch 0 taken 3 times.
✓ Branch 1 taken 56 times.
|
59 | } else if (fs->space_for_positive) { |
| 116 | 3 | str[len++] = ' '; | |
| 117 | } | ||
| 118 | 69 | s21_memcpy(str + len, int_buf, s21_strlen(int_buf)); | |
| 119 | 69 | len += s21_strlen(int_buf); | |
| 120 |
2/2✓ Branch 0 taken 66 times.
✓ Branch 1 taken 3 times.
|
69 | if (precision > 0) { |
| 121 | 66 | str[len++] = '.'; | |
| 122 | 66 | long double frac_scaled = frac_part * pow(10.0, precision); | |
| 123 | 66 | s21_size_t frac_int = (s21_size_t)(frac_scaled + 0.5L); | |
| 124 | char frac_buf[64]; | ||
| 125 |
2/2✓ Branch 0 taken 277 times.
✓ Branch 1 taken 66 times.
|
343 | for (int i = precision - 1; i >= 0; i--) { |
| 126 | 277 | frac_buf[i] = (frac_int % 10) + '0'; | |
| 127 | 277 | frac_int /= 10; | |
| 128 | } | ||
| 129 | 66 | frac_buf[precision] = '\0'; | |
| 130 | 66 | s21_memcpy(str + len, frac_buf, precision); | |
| 131 | 66 | len += precision; | |
| 132 | } | ||
| 133 | 69 | str[len] = '\0'; | |
| 134 | 69 | } | |
| 135 | |||
| 136 | 48 | void uint_to_base(unsigned long num, char *str, int base, const char *digits) { | |
| 137 | 48 | int len = 0; | |
| 138 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 46 times.
|
48 | if (num == 0) { |
| 139 | 2 | str[len++] = '0'; | |
| 140 | } else { | ||
| 141 |
3/4✓ Branch 0 taken 222 times.
✓ Branch 1 taken 46 times.
✓ Branch 2 taken 222 times.
✗ Branch 3 not taken.
|
268 | while (num && base) { |
| 142 | 222 | str[len++] = digits[num % base]; | |
| 143 | 222 | num /= base; | |
| 144 | } | ||
| 145 | } | ||
| 146 |
2/2✓ Branch 0 taken 108 times.
✓ Branch 1 taken 48 times.
|
156 | for (int i = 0; i < len / 2; i++) { |
| 147 | 108 | char tmp = str[i]; | |
| 148 | 108 | str[i] = str[len - 1 - i]; | |
| 149 | 108 | str[len - 1 - i] = tmp; | |
| 150 | } | ||
| 151 | 48 | str[len] = '\0'; | |
| 152 | 48 | } | |
| 153 |