Б. Страуструп - Язык программирования С++. Специальное издание, 3-изд. Бином. 2004 (1160791), страница 148
Текст из файла (страница 148)
Стандартная библиотека С Стандартная библиотека Сы-ы- унаследовала из библиотеки С функции для работы с С-строками. В этот раздел включены несколько самых полезных из них. Описание не предполагается исчерпывающим, и за дополнительной информацисй обращайтссь к вашему справочному руководству, Учтите, что разработчики реализаций часто добавляют в стандартные заголовочные файлы свои собственные нестандартные функции, поэтому очень легко запутаться, какие функции гарантированно доступны для всех реализаций, а какие нет. Заголовочные фай.л ы, представляющие возможности стандартной библиотеки С, перечислены в 9 16.1.2. Функции распределения памяти можно найти в 9 19А.6, функции ввода!'вывода языка С вЂ” в 9 21.8, а математическую библиотеку С -- в э 22.3.
Функции, относящиеся к запуску и завершению программ, описаны в э 3.2 и 6 94,1.1, а возможности чтения неопределенных ар!умептов функции представлены в 9 7.6. Функции в стиле С для строк с расширенным набором символов находятся в <си!айаг> и <втсйаг Ь>. Глава 20. Строки ббб Считается, что указате.ль не равен нулю, а массив элементов сйаг, на который он указывает, закан сивается нулем О. Функции я1гп, если в строке не набирается и элементов для копирования, останавливаются прн обнаружении нуля. Сравнение строк возвращает О, если строки равны, отрицательное число — если первый аргумент лексикографически следует до второго, и положительное число в противном случае.
Естественно, С не обеспечивает пар перегруженных функций. Однако, они нужны в С++ для обеспечения константных вызовов. Например: /1 С.н- иоЫЯсопя1 сЪа~ рос, слог' рс) ( // ошибка: сопз1 спас нельзя присваивать // правильно, но неаккурсипно: в рс л~ожет // не оказаться 'а' *я(гсуг (рос, 'а') = 'Ь'; *яггсуг (рс, 'а') = 'Ь'; /* функция из стандпрт ной библиотеки С, не С Н- */ слаг" яггсуг(сопя1 сааг' р, (п1с); /' С, в С++ не сколтилируетсл '/ оо(д у (сопя1 суаг' рос, сдаг' рс) /' преобразует сопз1 в не-сопя1: правильно на С, ошибка на С»» */ 'я(гсйг (рос, 'а ) = 'Ь'; /* правильно и на С, и на С»» '/ *яггсуг (рс, 'а') = 'Ь', По мере возможности С-строк лучше избегать, предпочитая им строки я1ппу.
С-строки и связанные с ними стандартные функции можно использовать для получения очень эффективного кода, но даже опытные программисты на С и С++ порой допускают при работе с ними «глупые ошибки». Однако программист на С++ не может не встретить некоторые из атих функций в старом коде. Здесь я приведу бессмысленный пример, иллюстрирующий наиболее распространенные функции: иогчЦ(сБаг" р, суаг«у) ( (Г (р==д) ге1игп; Ц (я1гстр (р, у)==0) ( (п1(=ягс!еп 'Зз); // указатели равны // значения строк равны //число символов (не считая конца строки) сйаг Ьи/(200]; зггсру (Ьи/, р); // копирование р в Ьи/(включая конец шпроки] // неаккуратно: когда-нибудь переполнится // копирование 200 символов из р в Ьи/ // неаккурапто: когда- нибудь не удастся // скопировагпь завершаю~циб символ я1 ору (ЬиЯ р, 200); //- Функция я1гс/гг () в С++ не позволяет записывать в константный аргумент.
Однако программы на С могут «воспользоваться преимуществом» более слабого контроля типов в С в функции я1гс/сг (); ЕЕ7 20.4. Стандартная библиотека С Символы-разделители в начале игнорирусотся. Если входная строка не представляет собой число, возвращается О. Например, значение а1ос ("семь") равно О. Если в вызове я1г1о1 (р, епс/, 6) значение влас не равно нулю, положение первого непрочитагиюго символа во входной строке может быть доступно через присвоение *епс/. Если Ь О, число интерпретируется как целый литерал С++ 1см. 2 44.1). Например, префикс Ох означает шестнадцатеричное число, 0 — восьмеричное и т, д. Что произойлет, если через аго/'(), атос () или а1о1 () преобразовывать величины, которые не имеют представления в соответствующем возвращаемом типе, не определено.
Если входная строка я/г/о1 () представляет число, которое не может быть представлено через !опт сп1, или если входная строка в/ггос/ представляет число, непредставимое через с/оиЬ/е, то переменная еггпо Я 16.1.2, ~ 22.3) устанавливается в Ш16ССгЕ, и возвращается соответствующее очень большое или очень маленькое значение. За исключением обработки ошибок, а1оЯв) эквивалентно в/г1оа) (я,О), а/ос (я) эквивалентно сп1 я1г/о!(я,0,10) и а(о/(в) эквивалентное/г/о1(в,0,10).
20.4.2. Классификация В <с1уре й> и <сс1уре> станда ций для работы с символами симаслОВ ртная библиотека предоставляет набор полезных функ- из ЛБСН и других подобных ему наборов: //буква: 'ацуг"А'..'7'сслсестнолс алфавите С /у" 20 2 1, у 2!.7) // буква в верхнем регистре: 'А' .. '77 //влсессгсном алфавите С /у 20.2.!, у 2!.7) О буква в нижнелс регистре: 'а' .. 'г' //влсешннолс олфаеите С /у 20.2.1, у 2!.7) 0 '0' .. 'У' // '0' .. '9' или буква // сил!воли-разделители //управляющие символа /А5С!!0..0! и !27) // пунктуация: ни один символ из вьссиеупогсянутих // !яа!рйа О ( !яас!у!! Г) О то, чпсо лсожно напечататьк аяс!!' ' ..
'-' // Иа!рйа /) ( !яд!у!1/) ( Ирипс! !) // эквивалент с в верхнелс регистре ! ! эквивалент с в нижнем регистре сп1!яа!рйа (!л1)! !п1 !яиррег (тф тс ся1осоес (т1); тссясйун (спс); сп! !яхй!усс(т1); !пс !яярасе (т1); т1 !ясп!г! (т ф !п1 сярипс1 (!пС); !п1 !яа1лит (тф !и! !ярг!л! (!пс)! сп1 !загар 6 (сл1), т1 1оиррег(сп1с); !л! 1о!осоег (1п1 с); ) Все они обычно реализуются простым поиском с использованием символа в качестве индекса в таблице атрибутов символов. Это значит, что такие конструкции, как; Ввод и вывод С-строк обычно производится при помощи семейства функций рг!п1~' 6 21.8).
В <в/с/!!Ь.й> и <св/ас!!6> стандартная библиотека вводит полезные функции для преобразования строк, представляющих численные значения, в сами численные значения: доиЫе асс/(соля! сйаг*р); //преобразует р// в допив /"а!рйп 1о//оа!!па") йоиЫе я1г1од (соля1сйаг' р, сйас "епд), //преобразует р// е доиЫе /"я!пад!одоиие") 1л! а!о! (солИ сйаг'р), // преобрадсет р// в десятичньсйт! !опд а1о! (сопяссйаГ р); //преобризует р// в десятичный !ассу 1опу я!с!о! (сопя! сйаг" р, сйаг'* елс/, !л1 Ь); // преобразует р// в !снуло основанию Ь Глава 20. Строки 668 (1' ('а'<=с с<з с<='г') )) ('А'<=с 8 6 с<='У')) ( // с из сзфпвити? ?,?- неэффективны, пе говоря о нудности их написания и большой вероятности ошибок (на машинах с символьным набором ЕВСР1С через это сравнение пройдут н неалфавитные символы). Эти стандартные функции принимают в качестве аргумента)п1 н передаваемое целое должно быть представимо как ипз(дпес1 сЬаг или ЕОЕ (который чаще всего имеет значение -1).
Это может оказаться проблемой в системах, где тип сЬаг имеет знак (см. 9 20,6[11)). Аналогичные функции для расширенных символов находятся в заголовочных файлах <ссис1уре' и <твс1уреЬ>, 20.5. Советы [1) Функциям с С-строками предпочитайте операции со з1ппа; з 20.4.1. [2) Пользуйтесь типом з1ппд для переменных и членов, а не как базовым классом; ~ 20.3, ~ 25.2.1.
[3) Вы можете передавать строки з1г1пд как аргументы по значению и возвращать нх по значению, предоставив системе самой заботиться о распределении памяти; ~ 20.3.6. [4) Когда вы хотите проверять диапазон, пользуйтесь а1(), а не нтераторами и [); % 20.3.2, ~ 20.3.5, [5) Когда вы хотите оптимизировать скорость, пользуйтесь итераторами или индексацией П, а не а1 (); Э 20.3.'2, 9 20.3.5. [6) Прямо или косвенно пользуйтесьзибз1г(), чтобы считывать подстроки, и гер1асе (), чтобы записывать подстроки; 9 20.3.12, 9 20.3.13. [7) Чтобы локализовать значение внутри з1ппд, пользуйтесь операциями Дпс( () (а не пишите явный цикл); 9 20.3,11. [8) Если к з1ппд нужно эффективно добавить символы, пользуйтесь аррепс1 (); э 20.3.9.
[9) Если быстродействие пекритично, используйте строки з1ппддля символьного ввода; э 20.3.5. [10) Для обозначения <остаток строкиь пользуйтесь записьюз1пидзпроз; 9 20З5. [11) При необходимости реализуйте интенсивно используемые классы строк с помогцью операций низкого уровня (не применяй~с низкоуровневые структуры данных повсюду); э 20.3.5. [12) Если вы пользуетесь типом з1ппд, где-нибудь перехватывайте исключения 1епатЬ еггог н ои1 о~ гниде; Э 20.3.5. [13) Будьте осторожны; не передавайте сЬаг* со значением 0 в функцию, работающую со строками з1ппд; ч 20.3.5.
[14) Пользуйтесь с з1гдля того, чтобы получить представление строки ввиде С-строки только тогда, когда это необходимо; э 203.7. [15) Когда хотите узнать вид символа (алфавитный, число, н т. д.), пользуйтесь 1за1рЬа (), 1зйй11() и т. п,, а не пишите собственные проверки; 9 20А.2. 20.6. Упражнения 669 20.6. Упражнения Решение некоторых задач к этой главе можно найти, просмотрев исходный текст реализации стандартной библиотеки. Сделайте одолхгение — попытайтесь найти собственные решения, прежде чем смотреть, как к этим проблемам подошел разработчик вашей библиотеки.