-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsscanf_conversions.c
More file actions
122 lines (115 loc) · 3.19 KB
/
sscanf_conversions.c
File metadata and controls
122 lines (115 loc) · 3.19 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#include "s21_string.h"
bool s21_isdigit(int c) { return c >= '0' && c <= '9'; }
long double s21_strtod(const char *string, char **endptr, int width) {
long double result = 0.0;
int sign = 1;
const char *start = string;
if (width == 0) width = 64;
while ((*start == ' ' || *start == '\t') && width > 0) start++;
if (width > 0 && *start == '-') {
sign = -1;
start++;
width--;
} else if (width > 0 && *start == '+') {
start++;
width--;
}
while (width > 0 && *start >= '0' && *start <= '9') {
result = result * 10 + (*start - '0');
start++;
width--;
}
if (width > 0 && *start == '.') {
start++;
width--;
long double fraction = 0.1;
while (width > 0 && *start >= '0' && *start <= '9') {
result += (*start - '0') * fraction;
fraction /= 10;
start++;
width--;
}
}
if (width > 0 && (*start == 'e' || *start == 'E')) {
start++;
start = s21_strtod_exponent(start, &width, &result);
}
if (endptr) *endptr = (char *)(start == string ? string : start);
return result * sign;
}
const char *s21_strtod_exponent(const char *start, int *width,
long double *result) {
int exp_sign = 1;
int exponent = 0;
if (*width > 0 && *start == '-') {
exp_sign = -1;
start++;
(*width)--;
} else if (*width > 0 && *start == '+') {
start++;
(*width)--;
}
while (*width > 0 && *start >= '0' && *start <= '9') {
exponent = exponent * 10 + (*start - '0');
start++;
(*width)--;
}
*result *= powl(10, exp_sign * exponent);
return start;
}
const char *s21_strtol_digits(const char *start, long long int *result,
int base, int *width) {
int parsing_complete = 0;
while (*width > 0 && *start && !parsing_complete) {
int digit = -1;
if (*start >= '0' && *start <= '9')
digit = *start - '0';
else if (*start >= 'a' && *start <= 'z')
digit = *start - 'a' + 10;
else if (*start >= 'A' && *start <= 'Z')
digit = *start - 'A' + 10;
if (digit < 0 || digit >= base) {
parsing_complete = 1;
} else {
*result = (*result) * base + digit;
start++;
(*width)--;
}
}
return start;
}
long long int s21_strtol(const char *string, char **endptr, int base, int width,
char specifier) {
const char *start = string;
long long int result = 0;
int sign = 1;
if (width == 0) width = 64;
while ((*start == ' ' || *start == '\t') && width > 0) {
start++;
}
if (width > 0 && *start == '-') {
sign = -1;
start++;
width--;
} else if (width > 0 && *start == '+') {
start++;
width--;
}
if (specifier == 'x' || specifier == 'X' || specifier == 'i') {
if (*start == '0' && (*(start + 1) == 'x' || *(start + 1) == 'X')) {
width > 1 ? (start += 2, width -= 2) : (start++, width--);
base = 16;
}
}
if (specifier == 'o' || specifier == 'i') {
if (*start == '0' && (*(start + 1) >= '0' && *(start + 1) <= '7')) {
start++;
width--;
base = 8;
}
}
if (base != 16 && base != 8) base = 10;
start = s21_strtol_digits(start, &result, base, &width);
if (endptr) *endptr = (char *)start;
return result * sign;
}