14.2. Работа со строками Xerces
14.2. Работа со строками Xerces
Проблема
Требуется обеспечить надежную и простую работу со строками с расширенным набором символов, используемыми библиотекой Xerces. В частности, необходимо уметь сохранять строки, возвращаемые функциями библиотеки Xerces, а также выполнять преобразования между строками Xerces и строками стандартной библиотеки С++.
Решение
Сохранять строки с расширенным набором символов, возвращаемые функциями библиотеки Xerces, можно с помощью шаблона std::basic_string, специализированного типом с расширенным набором символов XMLCh библиотеки Xerces.
typedef std::basic_string<XMLCh> XercesString;
Для выполнения преобразований между строками Xerces и строками, состоящими из стандартных символов, используйте перегруженный статический метод transcode() из класса xercesc::XMLString, который определен в заголовочном файле xercesc/util/XMLString.hpp.
В примере 14.4 определяются две перегруженные вспомогательные функции, toNative и fromNative, которые используют transcode для преобразования строк со стандартными символами в строки Xerces и обратно. Каждая функция имеет две версии: одна принимает строку в C-стиле, а другая принимает строку стандартной библиотеки С++. Для выполнения преобразований между строками Xerces и строками со стандартными символами вполне достаточно иметь эти служебные функции; после того как вы определили эти функции, вам уже никогда не потребуется вызывать непосредственно transcode.
Пример 14.4. Заголовочный файл xerces_strings.hpp, используемый для выполнения преобразований между строками Xerces и строками со стандартными символами
#ifndef XERCES_STRINGS_HPP_INCLUDED
#define XERCES_STRINGS_HPP_INCLUDED
#include <string>
#include <boost/scoped_array.hpp>
#include <xercesc/util/XMLString.hpp>
typedef std::basic_string<XMLCh> XercesString;
// Преобразует строку со стандартными символами
// в строку с расширенным набором символов
inline XercesString fromNative(const char* str) {
boost::scoped_array<XMLCh> ptr(xercesc::XMLString::transcode(str));
return XercesString(ptr.get());
}
// Преобразует строку со стандартными символами
// в строку с расширенным набором символов.
inline XercesString fromNative(const std::string& str) {
return fromNative(str.c_str());
}
// Преобразует строку с расширенным набором символов
// в строку со стандартными символами.
inline std::string toNative(const XMLCh* str) {
boost::scoped_array<char> ptr(xercesc::XMLString::transcode(str));
return std::string(ptr.get());
}
// Преобразует строку с расширенным набором символов в строку со стандартными символами.
inline std::string toNative(const XercesString& str) {
return toNative(str.c_str());
}
#endif // #ifndef XERCES_STRINGS_HPP_INCLUDED
Для выполнения преобразований между строками Xerces и std::wstring просто используйте конструктор std::basic_string, передавая ему два итератора. Например, можно определить следующие две функции.
// Преобразует строку Xerces в строку std::wstring
std::wstring xercesToWstring(const XercesString& str) {
return std::wstring(str.begin(), str.end());
}
// Преобразует строку std::wstring в строку XercesString
XercesString wstringToXerces(const std::wstring& str) {
return XercesString(str.begin(), str.end());
}
В этих функциях используется тот факт, что wchar_t и XMLCh являются интегральными типами, каждый из которых может неявно преобразовываться в другой; это должно работать независимо от размера wchar_t, пока не используются значения, выходящие за диапазон XMLCh. Вы можете определить подобные функции, принимающие в качестве аргументов строки в C-стиле, используя конструктор std::basic::string, которому передаются в качестве аргументов массив символов и длина.
Обсуждение
Для представления строк в коде Unicode библиотека Xerces использует последовательности символов XMLCh, завершаемые нулем. Тип XMLCh вводится с помощью typedef как интегральный тип, зависящий от реализации и содержащий не менее 16 бит, которых достаточно для представления символов почти любого языка. Xerces применяет символьную кодировку UTF-16, что подразумевает теоретическую возможность представления некоторых символов в коде Unicode в виде последовательности из нескольких символов XMLCh; однако практически можно считать, что каждый символ XMLCh непосредственно представляет один символ в коде Unicode, т.е. имеет числовое значение символа Unicode.
Одно время тип XMLCh определялся с помощью typedef как wchar_t, что позволяло легко сохранять копию строки Xerces как std::wstring. Однако в настоящее время Xerces определяет XMLCh на всех платформах с помощью typedef как unsigned short. Кроме всего прочего это означает, что на некоторых платформах типы XMLCh и wchar_t имеют разный размер. Поскольку Xerces может изменить в будущем определение XMLCh, нельзя рассчитывать на то, что XMLCh будет идентичен какому-то конкретному типу. Поэтому, если требуется сохранить копию строки Xerces, следует использовать тип std::basic_string<XMLCh>.
При использовании Xerces вам придется часто выполнять преобразования между строками со стандартными символами и строками Xerces; для этой цели в Xerces предусмотрена перегруженная функция transcode(). transcode() может преобразовать строку Unicode в строку со стандартными символами, использующую «родную» кодировку символов, или строку с «родной» кодировкой со стандартными символами в строку Unicode. Однако смысл родной кодировки точно не определен, поэтому если вы программируете в среде, в которой часто используется несколько кодировок символов, то вам придется все взять в свои руки и выполнять преобразования особым образом, используя либо фасет std::codecvt, либо подключаемые службы перекодировки (pluggable transcoding services) библиотеки Xerces, описанные в документации Xerces. Однако во многих случаях вполне достаточно использовать transcode().
Память под возвращаемые функцией transcode() строки, завершающиеся нулем, динамически выделяется при помощи оператора new в форме массива; вам придется строку удалять самому, используя оператор delete[]. Это создает небольшую проблему управления памяти, поскольку обычно требуется копировать строку или записывать ее в поток до ее удаления, а эти операции могут выбросить исключение. Я решаю эту проблему в примере 14.4 с помощью шаблона boost::scoped_array, который динамически выделяет память под массив и автоматически удаляет его при выходе из области видимости, даже если выбрасывается исключение. Например, рассмотрим реализацию функции fromNative.
inline XercesString fromNative(const char* str) {
boost::scoped_array<XMLCh> ptr(xercesc::XMLString::transcode(str));
return XercesString(ptr.get());
}
Здесь ptr становится обладателем возвращенной функцией transcode() строки с нулевым завершающим символом и освобождает ее, даже если конструктор XercesString выбрасывает исключение std::bad_alloc.
Более 800 000 книг и аудиокниг! 📚
Получи 2 месяца Литрес Подписки в подарок и наслаждайся неограниченным чтением
ПОЛУЧИТЬ ПОДАРОКЧитайте также
Операции над строками
Операции над строками Как уже говорилось, строки можно сравнивать. Кроме того, строки можно объединять с помощью операции конкатенации (+), что мы уже не раз делали. Например:S1="Здравствуй";S2=",";S3="Мир!";S=S1+S2+" "+S3;В итоге переменная S будет содержать строку «Здравствуй,
R.16.6 Управление строками
R.16.6 Управление строками Для удобства написания программ, порождающих текст на С++, введена управляющая строка вида:#line константа "имяфайла" optОна задает значение предопределенному макроимени __LINE__ (§R.16.10), которое используется в диагностических сообщениях или при
3.3. Тонкости работы со строками
3.3. Тонкости работы со строками В этом разделе мы рассмотрим некоторые тонкости работы со строками, которые позволяют лучше понять, какой код генерирует компилятор при некоторых, казалось бы, элементарных действиях. Не все приведенные здесь примеры работают не так, как
Глава 4 Работа со строками и столбцами
Глава 4 Работа со строками и столбцами По умолчанию лист книги в программе Excel содержит ячейки с одинаковыми значениями ширины и высоты. В процессе работы вам неоднократно придется изменять высоту строк и ширину столбцов, соответственно, будут изменяться и размеры ячеек,
ФУНКЦИИ, РАБОТАЮЩИЕ СО СТРОКАМИ
ФУНКЦИИ, РАБОТАЮЩИЕ СО СТРОКАМИ Большинство библиотек языка Си снабжено функциями, работающими со строками. Рассмотрим четыре наиболее полезных и распространенных: strlen( ), strcat( ), strcmp( ) и strcpy( ). Мы уже применяли функцию strlen( ), которая находит длину строки.
9.2.1. Использование awk при работе со строками
9.2.1. Использование awk при работе со строками В качестве альтернативы, Bash-скрипты могут использовать средства awk при работе со
8.5 Работа со Строками
8.5 Работа со Строками Можно осуществлять действия, подобные вводу/выводу, над символьным вектором, прикрепляя к нему istream или ostream. Например, если вектор содержит обычную строку, завершающуюся нулем, для печати слов из этого вектора можно использовать приведенный выше
Игры со строками.
Игры со строками. Все нижеследующие программы, должны начитаться и продолжаться объяснениями пользователю, что ему следует сделать для продолжения работы программы. (2)Написать программу со следующим сценарием:пользователь вводит строку, нажимает Enter и далее варианты:а)
Подпрограммы для работы с символами и строками
Подпрограммы для работы с символами и строками function Chr(a: byte): char; Преобразует код в символ в кодировке Windows function ChrUnicode(a: word): char; Преобразует код в символ в кодировке Unicode function OrdUnicode(a: char): word; Преобразует символ в код в кодировке Unicode function UpperCase(ch: char): char;
Работа с ячейками, строками и столбцами таблицы
Работа с ячейками, строками и столбцами таблицы Word имеет богатый арсенал средств для форматирования таблиц. Такие инструменты доступны на контекстных вкладках Конструктор и Макет, которые появляются автоматически при установке курсора в любую ячейку таблицы.Вкладка