Directory: | ./ |
---|---|
File: | s21_sprintf_converters.c |
Date: | 2025-07-13 17:59:14 |
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 | 1972 | void int_to_str(long long num, char *str, const FormatSpecifier *fs) { | |
25 | 1972 | int len = 0; | |
26 |
4/4✓ Branch 0 taken 4 times.
✓ Branch 1 taken 1968 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 1 times.
|
1972 | if (!(num == 0 && fs->precision == 0)) { |
27 | 1971 | int is_negative = 0; | |
28 |
2/2✓ Branch 0 taken 1036 times.
✓ Branch 1 taken 935 times.
|
1971 | if (num < 0) { |
29 | 1036 | is_negative = 1; | |
30 | 1036 | num = -num; | |
31 | } | ||
32 | do { | ||
33 | 5820 | str[len++] = num % 10 + '0'; | |
34 | 5820 | num /= 10; | |
35 |
2/2✓ Branch 0 taken 3849 times.
✓ Branch 1 taken 1971 times.
|
5820 | } while (num); |
36 |
2/2✓ Branch 0 taken 36 times.
✓ Branch 1 taken 1971 times.
|
2007 | while (len < fs->precision) { |
37 | 36 | str[len++] = '0'; | |
38 | } | ||
39 |
2/2✓ Branch 0 taken 1036 times.
✓ Branch 1 taken 935 times.
|
1971 | if (is_negative) { |
40 | 1036 | str[len++] = '-'; | |
41 |
2/2✓ Branch 0 taken 28 times.
✓ Branch 1 taken 907 times.
|
935 | } else if (fs->show_sign) { |
42 | 28 | str[len++] = '+'; | |
43 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 905 times.
|
907 | } else if (fs->space_for_positive) { |
44 | 2 | str[len++] = ' '; | |
45 | } | ||
46 |
2/2✓ Branch 0 taken 2963 times.
✓ Branch 1 taken 1971 times.
|
4934 | for (int i = 0; i < len / 2; i++) { |
47 | 2963 | char tmp = str[i]; | |
48 | 2963 | str[i] = str[len - 1 - i]; | |
49 | 2963 | str[len - 1 - i] = tmp; | |
50 | } | ||
51 | } | ||
52 | 1972 | str[len] = '\0'; | |
53 | 1972 | } | |
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 | 46 | void uint_to_base(unsigned long num, char *str, int base, const char *digits) { | |
137 | 46 | int len = 0; | |
138 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 44 times.
|
46 | if (num == 0) { |
139 | 2 | str[len++] = '0'; | |
140 | } else { | ||
141 |
3/4✓ Branch 0 taken 207 times.
✓ Branch 1 taken 44 times.
✓ Branch 2 taken 207 times.
✗ Branch 3 not taken.
|
251 | while (num && base) { |
142 | 207 | str[len++] = digits[num % base]; | |
143 | 207 | num /= base; | |
144 | } | ||
145 | } | ||
146 |
2/2✓ Branch 0 taken 101 times.
✓ Branch 1 taken 46 times.
|
147 | for (int i = 0; i < len / 2; i++) { |
147 | 101 | char tmp = str[i]; | |
148 | 101 | str[i] = str[len - 1 - i]; | |
149 | 101 | str[len - 1 - i] = tmp; | |
150 | } | ||
151 | 46 | str[len] = '\0'; | |
152 | 46 | } | |
153 |