- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 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
typedef enum { SUCCESS = 0, NOTNUMBER = 1, BOUNDS = 2, EOFREACHED = 3 } rdstat_t;
int flush_line(FILE *stream) {
int ch;
do {
ch = fgetc(stream);
} while (ch != EOF && ch != '\n');
return ch;
}
/* enough to contain (1 + length of ASCII string of SIZE_MAX
decimal representation) characters */
#define SIZE_T_BUF_SIZE 100
/* reads until newline or EOF, writes (size_t *out) if success */
rdstat_t read_size_t(FILE *stream, size_t *out) {
char str_SIZE_MAX[SIZE_T_BUF_SIZE];
snprintf(str_SIZE_MAX, SIZE_T_BUF_SIZE, "%zu", SIZE_MAX);
char buf[SIZE_T_BUF_SIZE];
if (!fgets(buf, SIZE_T_BUF_SIZE, stream))
return EOFREACHED;
if (buf[strlen(buf) - 1] != '\n') {
flush_line(stream);
return NOTNUMBER;
}
buf[strlen(buf) - 1] = 0;
char *ch;
for (ch = buf; *ch; ++ch)
if (!isdigit(*ch))
return NOTNUMBER;
if (strlen(buf) == strlen(str_SIZE_MAX) && strcmp(buf, str_SIZE_MAX) > 0)
return BOUNDS;
sscanf(buf, "%zu", out);
return SUCCESS;
}
Наваял функцию для чтения size_t из файла с защитой от дурака (писал код будучи больным, чесслово).
Ничего умнее печати SIZE_MAX в строчку и лексикографического сравнения для проверки границ введенного числа не придумал %)