/* превращает строку в целое число и сообщает о состоянии */
stoi(string, intptr)
char string[ ]; /* строка, подлежащая преобразованию в целое*/
int *intptr; /* значение целого */
{
int sign = 1; /* проверяет наличие знака + или - */
int index = 0;
if(string[index] == '-' || string[index] == '+')
sign = (string[index ++] == '-') ? -1 : 1; /* установить знак */
*intptr = 0; /* начальное значение */
while(string[index] >= '0' && string[index] <= '9')
*intptr = 10 * (*intptr) + strmg[index++] - '0';
if(string[index] == '\0')
{
*intptr = sign * (*intptr);
return(YESNUM); }
else /* найден символ, отличный от цифры, знака или ' \0' */
return(NONUM);
}
Оператор whileпродолжает работу, преобразуя цифры в числа, пока не достигнет нецифрового символа. Если это символ '\0', все прекрасно, потому что он означает конец строки. Любой другой нецифровой символ отсылает программу к elseдля сообщения об ошибке.
Стандартная библиотека языка Си содержит функцию atoi( )(перевод кода ASCII в целое число), очень похожую на stoi( ). Основная разница заключается в том, что stoi( )проверяет на нецифровые строки, a atoi( )использует returnвместо указателя, для возврата числа, и пропускает пробел, как мы это делали в getint(). Можно было бы осуществить все проверки состояния в getint( )и использовать atoi( )вместо stoi( ), но мы полагаем, что было бы интереснее разрабoтать нашу собственную версию.
Так ли уж правильны наши рассуждения? Давайте проверим нашу функцию на учебной программе:
/* проверка функции getint( )*/
#define STOP - 1
#define NONUM 1
#define YESNUM 0
main( )
{
int num, status;
printf(" Программа прекращает считывание чисел, если встречает EOF. \n" );
while((status = getint(&num)) != STOP)
if(status = = YESNUM)
printf(" Число %d принято. \n", num);
else
printf(" Это не целое число! Попытайтесь снова. \n");
printf("Этo оно. \n");
}
Вот пример работы программы:
Программа прекращает считывание чисел, если встречает EOF.
100 -23
Число 100 принято.
Чмсло -23 принято.
+892.
Число 892 принято.
wonk
Это не целое число! Попытайтесь снова.
23skidoo
Это не целое число! Попытайтесь снова.
775
Число 775 принято.
Клавиша [control z] (посылает символ EOF в нашу программу).
Это оно.
Как видите, программа выполняется. Обратите внимание на то, как мы сумели организовать цикл для неограниченного считывания целых чисел до тех пор, пока не будет введен символ EOF. Это удобное свойство.
Есть ли здесь ошибки? По меньшей мере одна. Если непосредственно за числом следует символ EOFбез разделяющего пробела или символа новой строки, ввод прекращается, и это число не принимается во внимание:
706 EOF /* 706 принято*/
706 EOF /* 706 не принято*/
Мы не хотели делать пример слишком сложным, поэтому допустили возможность этой ошибки. Дальнейшую разработку программы, как мы думаем, может осуществить сам читатель в качестве упражнения.
Одним из наиболее распространенных тестов для машин является сортировка. Мы хотим разработать программу для сортировки целых чисел. Снова применим принцип черного ящика и подумаем в терминах ввода и вывода. Наш общий замысел, показанный на рис. 10.4, довольно прост.

РИС. 10.4. Программа сортировки, рассматриваемая как черный яшик
На данном этапе программа еще недостаточно определена, чтобы ее кодировать. Следующий шаг заключается в определении главных задач, которые должна выполнить программа для достижения поставленных целей. Их три:
1. Считывание чисел.
2. Сортировка чисел.
3. Печать отсортированных чисел. На рис. 10.5 показано это разделение при движении от верхнего уровня конструкции вниз к более детальному.

РИС. 10.5 Программа сортировки: содержание
Теперь мы имеем три черных ящика, каждый со своим входом и выходом. Можно передать каждую часть разным группам программистов, если мы уверены в том, что числа, выводимые блоком "считывание", представлены в той же самой форме, которую использует блок "сортировка" для ввода.
Читать дальше