63 lines
2.5 KiB
C
63 lines
2.5 KiB
C
#include "4_3_getch.h"
|
||
#include <ctype.h>
|
||
#include <signal.h>
|
||
#include <stdio.h>
|
||
|
||
/**
|
||
* @brief Функция чтения первого токена-числа из ввода stdin
|
||
*
|
||
* @param pn - указатель на int, в который требуется записать считанное число
|
||
* @return последний считанный символ `c`
|
||
*/
|
||
int getint(int *pn)
|
||
{
|
||
int c; /* Это последний считанный символ в процессе работы функции */
|
||
int sign; /* Тут хранится 1 или -1 в зависимости от того, какой sing пришел у
|
||
числа */
|
||
|
||
/* Пока у нас приходят пробелы - берем следующий символ через getch()) */
|
||
while (isspace(c = getch()))
|
||
;
|
||
|
||
if (!isdigit(c) && c != EOF && c != '+' && c != '-')
|
||
{
|
||
/* В случае, если пришло не число и не знак - пихаем его в буфер.
|
||
* Пихаем мы в буфер со следующей целью - допустим у нас ситуация:
|
||
* На вход пришло " x123", тогда получается что на вход пришло не число.
|
||
* Т.е. getch() уже прочитал "х", то нам его надо как-то вернуть обратно для
|
||
* следующих парсеров. Следовательно перед тем, как выйти с кодом 0 (что
|
||
* означает что пришло не число) - мы записываем в буфер значение "х".
|
||
* Следующий парсер который начнет это читать - начент чтение с "х" из
|
||
* буфера.*/
|
||
ungetch(c);
|
||
return 0;
|
||
}
|
||
|
||
sign = (c == '-') ? -1 : 1;
|
||
if (c == '+' || c == '-')
|
||
c = getch();
|
||
/*
|
||
* Пример парсинга "158":
|
||
* старт: *pn = 0
|
||
* '1' -> *pn = 10*0 + 1 = 1
|
||
* '5' -> *pn = 10*1 + 5 = 15
|
||
* '8' -> *pn = 10*15 + 8 = 158
|
||
*
|
||
* Почему (c - '0'):
|
||
* '0'..'9' идут подряд в ASCII, поэтому разница кодов дает цифру:
|
||
* '0' - '0' = 0, '5' - '0' = 5, '9' - '0' = 9
|
||
*/
|
||
for (*pn = 0; isdigit(c); c = getch())
|
||
*pn = 10 * *pn + (c - '0');
|
||
*pn *= sign;
|
||
if (c != EOF)
|
||
ungetch(c);
|
||
return c;
|
||
}
|
||
|
||
int main()
|
||
{
|
||
int getint_result;
|
||
getint(&getint_result);
|
||
printf("Scanned int: %d\n", getint_result);
|
||
}
|