#include #include #include int match_space(FILE *f) { int ch; while ((ch = fgetc(f)) != EOF && isspace(ch)) {} if (ch != EOF) ungetc(ch, f); if (ferror(f)) return -1; return 1; } int match_char(FILE *f, char c) { int ch = fgetc(f); if (ch == c) return 1; if (ch != EOF) ungetc(ch, f); return -1; } int scan_char(FILE *f, va_list ap) { int ch = fgetc(f); char *cp = va_arg(ap, char *); if (ch == EOF) return -1; *cp = (char)ch; return 1; } int scan_int(FILE *f, va_list ap) { int *ip = va_arg(ap, int *); int value = 0; int sign = 1; int ch; ch = fgetc(f); if (ch == '-') { sign = -1; ch = fgetc(f); } else if (ch == '+') { ch = fgetc(f); } if (!isdigit(ch)) { if (ch != EOF) ungetc(ch, f); return -1; } while (isdigit(ch)) { value = value * 10 + (ch - '0'); ch = fgetc(f); } if (ch != EOF) ungetc(ch, f); *ip = value * sign; return 1; } int scan_string(FILE *f, va_list ap) { char *sp = va_arg(ap, char *); int i = 0; int ch; ch = fgetc(f); if (ch == EOF) return -1; while (ch != EOF && !isspace(ch)) { sp[i++] = (char)ch; ch = fgetc(f); } sp[i] = '\0'; if (ch != EOF) ungetc(ch, f); return 1; } int match_conv(FILE *f, const char **format, va_list ap) { switch (**format) { case 'c': return scan_char(f, ap); case 'd': match_space(f); return scan_int(f, ap); case 's': match_space(f); return scan_string(f, ap); case '\0': return -1; default: return -1; } } int ft_vfscanf(FILE *f, const char *format, va_list ap) { int nconv = 0; int c = fgetc(f); if (c == EOF) return EOF; ungetc(c, f); while (*format) { if (*format == '%') { format++; if (match_conv(f, &format, ap) != 1) break; else nconv++; } else if (isspace(*format)) { if (match_space(f) == -1) break; } else { if (match_char(f, *format) != 1) break; } format++; } if (ferror(f)) return EOF; return nconv; } int ft_scanf(const char *format, ...) { va_list ap; va_start(ap, format); int ret = ft_vfscanf(stdin, format, ap); va_end(ap); return ret; }