-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy paths21_sscanf.c
More file actions
85 lines (83 loc) · 2.36 KB
/
s21_sscanf.c
File metadata and controls
85 lines (83 loc) · 2.36 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
#include "s21_string.h"
int s21_sscanf(const char *str, const char *format, ...) {
if (!str || !format) return -1;
const char *string = str;
const char *start = str;
FormatParser parser = {.format = format};
int result = 0;
int continue_parsing = 1;
va_list args;
va_start(args, format);
while (continue_parsing) {
if (!parse_format(&parser)) {
continue_parsing = 0;
} else if ((!string || *string == '\0') && parser.specifier != 'n') {
continue_parsing = 0;
} else {
switch (parser.specifier) {
case '%':
string++;
break;
case 'u':
case 'd':
case 'X':
case 'x':
case 'i':
case 'o':
string = dScanSpecifier(string, args, &parser, &result);
break;
case 'c':
string = cScanSpecifier(string, args, &parser, &result);
break;
case 's':
string = sScanSpecifier(string, args, &parser, &result);
break;
case 'g':
case 'G':
case 'f':
case 'e':
case 'E':
string = fScanSpecifier(string, args, &parser, &result);
break;
case 'p':
string = pScanSpecifier(string, args, &parser, &result);
break;
case 'n':
string = nScanSpecifier(string, args, start);
break;
}
}
}
va_end(args);
while (*string == ' ' || *string == '\t') string++;
result = (result > 0 || s21_strlen(string) != 0) ? result : -1;
return result;
}
bool parse_format(FormatParser *parser) {
bool success = true;
while ((*parser->format == ' ') || (*parser->format == '\t'))
parser->format++;
if (*parser->format == '\0') success = false;
if (success && *parser->format != '%') success = false;
if (success) {
parser->format++;
parser->suppress = (*parser->format == '*');
if (parser->suppress) parser->format++;
parser->width = 0;
while (s21_isdigit(*parser->format)) {
parser->width = parser->width * 10 + (*parser->format - '0');
parser->format++;
}
parser->length = '\0';
if (*parser->format == 'h' || *parser->format == 'l' ||
*parser->format == 'L') {
parser->length = *parser->format;
parser->format++;
}
if (*parser->format != '\0') {
parser->specifier = *parser->format;
parser->format++;
}
}
return success;
}