Студопедия КАТЕГОРИИ: АвтоАвтоматизацияАрхитектураАстрономияАудитБиологияБухгалтерияВоенное делоГенетикаГеографияГеологияГосударствоДомЖурналистика и СМИИзобретательствоИностранные языкиИнформатикаИскусствоИсторияКомпьютерыКулинарияКультураЛексикологияЛитератураЛогикаМаркетингМатематикаМашиностроениеМедицинаМенеджментМеталлы и СваркаМеханикаМузыкаНаселениеОбразованиеОхрана безопасности жизниОхрана ТрудаПедагогикаПолитикаПравоПриборостроениеПрограммированиеПроизводствоПромышленностьПсихологияРадиоРегилияСвязьСоциологияСпортСтандартизацияСтроительствоТехнологииТорговляТуризмФизикаФизиологияФилософияФинансыХимияХозяйствоЦеннообразованиеЧерчениеЭкологияЭконометрикаЭкономикаЭлектроникаЮриспунденкция |
Использование класса CStringСтр 1 из 98Следующая ⇒
Работа со строками
Примеры преобразования строк символов в различные форматы представления см. в MSDN: Ms-help://MS.VSCC.v80/MS.MSDN.v80/MS.VisualStudio.v80.en/dv_vcmcpp/html/e7e4f741-3c82-45f0-b8c0-1e1e343b0e77.htm Эту ссылку надо поместить в элемент ввода URL в окне MSDN. Очень хорошо различные кодировки символов и обработка символов с строк в целом изложены в работе Д.Рихтера и Назара [«Работа с символами и строками» 8а]. Кодировки и кодовые страницы Обработка строк (символов) в языке С++ является, как на мой взгляд, одной из самых сложных или, скорее, запутанных задач. Это связано с наличием следующих, как говорят юристы, «отягчающих обстоятельств». Во-первых, наличие большого числа различных способов определения и обработки строк символов (библиотечных функций и целых классов). Во-вторых, слабая поддержка кодировки символов кириллицы (здесь имеются ввиду кодировки символов кириллицы в MS DOS и Windows) в инструментальных средствах. В-третьих, наличие многочисленных кодировок: ASCII (7 или 8 бит), ANSI (8 бит), Multibyte Character Sets (MBCSs – 16 бит), Unicode (UTF-7, UTF-8,UTF-16,UTF-32, UTF-32 Big-Endian). Терминология. Ucs Transformation Format (UTF) – формат преобразования UCS. Universal Character Set (UCS) – универсальный набор символов ISO 10646, надмножество Unicode, имеет 31-битовое кодовое пространство. Для справки. Найти кодовые страницы (CP – code page) и их краткую характеристику можно в MSDN (MVS-2005) по индексу Encoding class→About encoding class. Некоторые кодовые страницы приведены в табл. 2. Символ * в столбце «Примечание» означает, что кодовая страница непосредственным образом поддерживается инфраструктурой .NET вне зависимости от базовой платформы. Таблица 2 Краткая характеристика некоторых кодовых страниц
Если Вы хотите в своем программном коде разобраться с тем, какое число байт занимает символ или переменная какого-либо символьного типа, воспользуйтесь операцией sizeof.Например, в консольном приложении (среда MVS-2005) это можно сделать так: cout<<sizeof (char) <<endl; //выводит 1 cout<<sizeof (TCHAR) <<endl; /*выводит 2 или 1 в зависимости от выбранной кодировки */ cout<<sizeof (wchar_t)<<endl; //выводит 2 cout<<sizeof ('a') <<endl; //выводит 1
О кодировке Unicode Символы, используемые в европейских языках, можно закодировать восемью битами, даже символы с диакритическими знаками. Большинство азиатских языков для своих символов требуют 16 разрядов. Многие программы используют стандарт «набор двухбайтовых символов» (double-byte character set, DBCS), в котором некоторые символы кодируются 8, другие — 16 разрядами, в зависимости от значения первых 8 разрядов. DBCS сейчас (эти строки были написаны в 1998г.) заменяется Unicode, в которой все символы кодируются 16 разрядами. Для отдельных языков не выделяются отдельные наборы символов: например, если символ используется в японском и китайском, то этот символ лишь однократно входит в Unicode. Если посмотреть на исходный код MFC и на код, сгенерированный IDE, то можно видеть типы TCHAR, LPTSTR и LPCTSTR, а также строковые константы вида _T(“строка символов”). Перед нами макросы. Если собирать проект без определения символа препроцессора _UNICODE, компилятор сгенерирует код для обычных 8-разрядных символов ANSI (CHAR) и указателей на массивы 8-разрядных символов (LPTSTR и LPCTSTR). Если же определить _UNICODE, компилятор сгенерирует код для 16-разрядных символов Unicode (WCHAR), соответствующих указателей (LPWSTR и LPCWSTR) и строковых констант (L”wide string”). Символ препроцессора _UNICODE определяет также, какие функции вызываются приложением, так как многие функции Win32 существуют в двух версиях. Когда программа вызывает, например, CreateWindowEx(), компилятор генерирует код для вызова либо CreateWindowExA() (с параметрами ANSI) либо CreateWindowExW() (с параметрами Unicode). В Microsoft Windows NT, в которой используется Unicode, CreateWindowExW() передаст все параметры напрямую, тогда как CreateWindowExA() преобразует строковые (ANSI) и символьные параметры в Unicode. Если Вы хотите создать Unicode-приложение, его следует создавать для Windows NT и везде использовать макросы. Вызовы СОМ (за исключением DAO) всегда используют «широкие» (wide) символы (тип BSTR). Хотя и существуют функции Win32 для преобразования между ANSI и Unicode, но, используя класс CString, для этого можно прибегнуть к помощи Unicode-конструктора и функции-члена AllocSysString. Некоторые рекомендации и основные приемы по работе с символами кириллицы см. в конце следующего подраздела и в подразделах «Русификация приложений» и «Использование ini-файла».
Использование класса CString Этот MFC-класс значительно расширяет язык C++. Как указано в разделе “Microsoft Foundation Classes and Templates” интерактивной справки MSDN у класса CString много полезных операторов и функций-членов, но, по-видимому, главное его достоинство — способность динамически выделять память. Благодаря этому не надо заботиться о размере строки, выделении и освобождениии памяти и т.п. Вот несколько типичных примеров использования объектов CString: CString strFirstName("Elvis"); CString strLastName("Presley"); CString strTruth = strFirstName + _T(" ") + strLastName; // конкатенация strTruth += " is alive"; ASSERT(strTruth == "Elvis Presley is alive"); ASSERT(strTruth.Left(5) == strFirstName); /* функция Left возвращает подстроку, начинающуюся с начала строки заданной длины*/ ASSERT(strTruth[2] == 'v'); // операция индексирования
В совершенном мире программы на C++ всегда использовали бы объекты CString и никогда — обычные массивы символов с нулем в конце. Увы, многие функции стандартной библиотеки по-прежнему полагаются на эти массивы, поэтому программы должны уметь работать с обоими представлениями строк. К счастью, в классе CString есть оператор const char * (), преобразующий объект CString в указатель на символы. Многие функции библиотеки MFC требуют параметров типа const char *. Возьмем, к примеру, глобальную функцию AfxMessageBox() библиотеки MFC. Вот один из ее прототипов: int AFXAPI AfxMessageBox(LPCTSTR lpszText, UINT nType = MB_OK, UINT nIDHelp = 0);
Обратите внимание: LPCTSTR — это не указатель на объект CString, а заменитель для const char *, совместимый с Unicode. В программе, компилируемой для набора символов ANSI, можно использовать функцию AfxMessageBox так: char szMessageText[] = "Unknown error"; AfxMessageBox(szMessageText);
или так: CString strMessageText("Unknown error"); AfxMessageBox(strMessageText);
Теперь предположим, что надо создать строку в соответствии с определенным форматом. Эта задача решается при использовании функции Format: int nError = 23; CString strMessageText; strMessageText.Format("Error number %d", nError); AfxMessageBox(strMessageText);
Допустим, Вам понадобился прямой доступ к символам в объекте CString. Если Вы напишите примерно такой код: CString strTest("test"); strncpy(strTest, "T", 1);
то компилятор сообщит об ошибке, так как первый параметр функции strncpy() объявлен как char*, а не const char *. Функция CString::GetBuffer() фиксирует заданный размер буфера строки и возвращает char *. Чтобы потом вновь сделать строку динамической, вызовите функцию-член CString::ReleaseBuffer().Вот как правильно заменить строчную букву t прописной: CString strTest("test"); strncpy(strTest.GetBuffer(5), "T", 1); strTest.ReleaseBuffer(); ASSERT(strTest == "Test");
То же самое в программе, компилируемой для набора символов Unicode, должно выглядеть таким образом: wchar_t szMessageText[] = _T("Unknown error"); AfxMessageBox(szMessageText); CString strMessageText("Unknown error CString"); AfxMessageBox(strMessageText); int nError = 23; CString strMessageText; strMessageText.Format(_T("Error number %d"), nError); AfxMessageBox(strMessageText); CString strTest("test"); wcsncpy(strTest.GetBuffer(5),_T("T"),1); strTest.ReleaseBuffer(); ASSERT(strTest == "Test");
Оператор const char * преобразует объект CString в указатель на константу; но как быть с обратным преобразованием? У класса CString есть конструктор, преобразующий указатель на символьную константу в объект CString, и, кроме того, набор переопределенных операторов для таких указателей. Вот почему допустимы такие выражения, как: truth += "is alive";
Специальный конструктор работает с функциями, принимающими ссылку на CString, например с CDC::TextOut(). В следующем примере в стеке вызывающей программы создается временный объект CString, а его адрес передается в TextOut(): pDC-> TextOut(0,0,”Hello world!”);
Если Вы пишете функцию, принимающую строковый параметр, учтите несколько правил: · если функция не изменяет содержимое строки и Вы собираетесь работать со стандартными библиотечными функциями, такими как strcpy(), используйте параметр const char *; · если функция не изменяет содержимое строки, но Вы хотите вызывать в ней функции-члены CString, используйте параметр типа const CString &; · если функция изменяет содержимое строки, но Вы хотите вызывать в ней функции-члены CString, используйте параметр типа CString &.
Перечисленные преобразования работают с английскими символами, но не работают с символами кириллицы. Для преобразования символов кириллицы в кодировку MS DOS воспользуйтесь таким приемом: char Buf[300]; char * GetANSI(CString str) { WideCharToMultiByte(866,WC_NO_BEST_FIT_CHARS,str,-1,Buf,sizeof(Buf),0,0); return Buf; }
Если требуется получить символы в кодировке Windows, замените 866 на 1251. Еще одна функция: /*Ukr - Выполняет преобразование символов кириллицы из кодировки 1251 (Cyrillic (Windows) ) в кодировку 866 (Cyrillic DOS). Поддерживает символы как русского, так и украинского языков*/ char * Ukr(char Str[]) { static char Buf[1024]; strcpy_s(Buf,strlen(Str)+1,Str); /*в следующем цикле заменяем коды русских букв на коды украинских, не изменяя кодов остальных символов*/ for(int i=0;i<strlen(Buf);i++) switch (Buf[i]) { case -78 : Buf[i]=73; break; // І case -77 : Buf[i]=105; break; // і case -86 : Buf[i]=242; break; // Є case -70 : Buf[i]=243; break; // є case -81 : Buf[i]=244; break; // Ї case -65 : Buf[i]=245; break; // ї case -88 : Buf[i]=240; break; // Ё case -72 : Buf[i]=241; break; // ё default : { if((Buf[i]<=-17)&&(Buf[i]>=-64)) Buf[i]-=64; //А..Я,а..п else if((Buf[i]<=-1)&&(Buf[i]>=-16)) Buf[i]-=16; //р..я } } return Buf; } |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Последнее изменение этой страницы: 2018-04-12; просмотров: 419. stydopedya.ru не претендует на авторское право материалов, которые вылажены, но предоставляет бесплатный доступ к ним. В случае нарушения авторского права или персональных данных напишите сюда... |