Функция atoi() по-прежнему работает, если строка только начинается с целого числа. В таком случае она преобразовывает символы до тех пор, пока не встретит символ, не являющийся частью целого числа. Например, atoi ("42regular" ) возвращает целое число 42. А что, если командной строкой будет hello what? В нашей реализации С функция atoi() возвращает значение 0, если ее аргумент не распознается как числовой. Тем не менее, в стандарте С указано, что поведение в данном случае не определено. Функция strtol(), которая вскоре будет обсуждаться, обеспечивает более надежный контроль ошибок.
В программу включен заголовочный файл stdlib.h, потому что, начиная с ANSI С, он содержит объявление функции atoi(). В этом заголовочном файле также объявлены функции atof() и atoi(). Функция atof() преобразует строку в значение типа double, а функция atoi() — в значение типа long. Они работают аналогично atoi(), и поэтому имеют, соответственно, тип double и тип long.
Стандарт ANSI С предоставляет усложненные версии этих функций: strtol() преобразует строку в значение типа long, strtoul() — типа unsigned long, а strtod() — типа double. Более сложный аспект упомянутых функций связан с тем, что они идентифицируют и сообщают о первом символе в строке, который не относится к числу. Кроме того, функции strtol() и strtoul() позволяют указывать основание системы счисления.
Давайте рассмотрим пример, в котором задействована функция strtol(). Ее прототип имеет следующий вид:
long strtol(const char * restrict nptr, char ** restrict endptr, int base);
Здесь nptr — указатель на строку, подлежащую преобразованию, endptr — адрес указателя, который устанавливается в адрес символа, прекращающего ввод числа, и base — основание системы счисления, в которой записано число. Это поможет прояснить пример, приведенный в листинге 11.33.
Листинг 11.33. Программа strcnvt.c

472 глава 11

Ниже показаны результаты пробного запуска:
Введите число (или пустую строку для выхода из программы):
10
десятичный ввод, десятичный вывод: 10, прекращен на (0) шестнадцатеричный ввод, шестнадцатеричный вывод: 16, прекращен на (0) Следующее число: lOatom
десятичный ввод, десятичный вывод: 10, прекращен на atom (97) шестнадцатеричный ввод, шестнадцатеричный вывод: 266, прекращен на atom (116) Следующее число:
Программа завершена.
Прежде всего, обратите внимание, что строка "10" преобразуется в число 10, когда base равно 10, и в 16, когда base равно 16. Кроме того, если end указывает на символ, то *end — это сам символ. Следовательно, первое преобразование завершается, когда достигнут нулевой символ, поэтому end указывает на нулевой символ. Таким образом, вывод end приводит к отображению пустой строки, а вывод *end с форматом %d — к отображению ASCII-кода нулевого символа.
Для второй строки ввода (в интерпретации с десятичным представлением) указатель end получает адрес символа ' а'. Тогда вывод указателя end приводит к отображению строки "atom", а вывод *end — к отображению ASCII-кода символа ' а '. Однако, как только base изменяется на 16, символ 'а' распознается как допустимая шестнадцатеричная цифра, и функция преобразует шестнадцатеричное число 10а в десятичное 266.
Функция strtol() работает с системами счисления, имеющими основание вплоть до 36, применяя в качестве цифр все буквы английского алфавита до ' z'. Функция strtoul() делает то же самое, но преобразует значения без знака.
Символьные строки и строковые функции 473
Функция strtod() работает только в десятичной системе счисления, так что она принимает только два аргумен та.
Многие реализации располагают функциями itoa() и ftoa(), предназначенными для преобразования целочисленных значений и значений с плавающей запятой в строки. Тем не менее, они не являются частью стандартной библиотеки С, поэтому для большей совместимости используйте вместо них sprintf().
Ключевые понятия
Многие программы имеют дело с текстовыми данными. Программа может предложить ввести ваше имя, список корпораций, адрес, ботаническое название папоротника, музыкальное сопровождение и т.п.; поскольку мы взаимодействуем с окружающим миром посредством слов, примерам применения текста на самом деле нет конца. Строки являются средством, используемым в программах на С для обработки текста.
Строка в С, независимо от того, как она идентифицирована — символьным массивом, указателем или строковым литералом, — хранится в виде последовательности байтов, содержащих коды символов, и эта последовательность завершается нулевым символом. Учитывая удобство строк, в С предоставлена библиотека функций для манипулирования, поиска и анализа строк. В частности, имейте в виду, что при сравнении строк вы должны применять функцию strcmp(), а не операции отношений, а для присваивания строки символьному массиву — функцию strcpy() или strncpy() вместо операции присваивания.
Читать дальше