![]() |
Модераторы: bsa |
![]() ![]() ![]() |
|
papam |
|
||||||||||||||||||||||||||||||||||||||||||||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 104 Регистрация: 2.2.2006 Где: Украина::Запорожь е Репутация: 2 Всего: 4 |
Всем Доброго времени суток! В данной статье речь идет о преобразовании символьной информации между двумя кодировками OEM и ANSI в ОС Windows Метод первый : Локализация Локализация в первую очередь используется в потоках ввода/вывода стандарьной библиотеки. Программа открывает для чтения существующий файл и закрывает его. В противном случае ругается. Имя файла вводит пользователь. Причем предполагается, что файл находится в текущем каталоге (каталоге с нашим проектом). У меня проект называется Listing5, поэтому я в этой самой папке заранее создал текстовый файлик с именем Файлик.txt Начнем с функции setlocale. Она нужна для установки, изменения или определения программной локали и имеет такой вид:
category – категория (тип) изменения локали; locale – имя (название) локали; Первый параметр может принимать шесть различных значений, нам же подойдут два: LC_ALL или LC_CTYPE. При использовании первого варианта изменения коснутся всех категорий, при использовании второго варианта изменения коснутся функций, работающих с символами. Второй параметр представляет собой имя национальных особенностей. Это может быть просто имя, например, “French” или же имя вместе с указанным через точку номером кодовой страницы “French_Canada.1252” или же только номер кодовой страницы “.866” . Можно не вспоминать номер кодовой страницы и поставить “.OCP” – текущий номер для OEM, определенный в операционной системе. Дальше в программе объявляется prompt - строка С-стиля. Здесь же она инициализируется строковым литералом с префиксом L. Префикс L указывает, что данная строка является строкой символов из расширенного набора (Unicode) и имеет тип const wchar_t[]. Дальше объявляется строка типа wstring. Это тот же самый string, но состоящий не из ANSI-символов, а из Unicode-символов (тип которых wchar_t). Затем идет диалог с пользователем и инициализация filename строчкой, которую вводит пользователь. Последняя часть – собственно действия над файлом. Объявляется указатель на структуру FILE, которая содержит в себе информацию о текущем состоянии потока; используется во всех потоковых операциях ввода/вывода. Затем файл открывается с помощью функции [B]_wfopen[/b] (версия функции fopen стандартной библиотеки, но для Unicode). Эта функция принимает в качестве параметров имя файла и атрибут. В нашем случае это
В случае ошибки функция
Функция
Пример:
Пример 2:
Метод второй: функции SetConsoleCP и SetConsoleOutputCP Вот эти функции:
Разница между этими двумя функциями такая:
Чтобы узнать текущий номер кодовой страницы консоли, мы можем использовать вот эти две функции:
Эти функции не принимают параметров, а возвращают текущий номер кодовой страницы консоли. Разница между ними такая же, как и у двух предыдущих - все ясно из названия. Более то, чтобы не мучаться с таблицами всех этих номеров, есть ещё две функции:
Обе функции без параметров, первая возвращает текущий номер кодовой страницы в ANSI, вторая - в OEM. Следовательно, эти функции очень удобно использовать в качестве параметров для функций:
Эти функции работают не всегда. Смотрите, какие у них требования: Client: Included in Windows XP, Windows 2000 Professional, and Windows NT Workstation. Server: Included in Windows Server 2003, Windows 2000 Server, and Windows NT Server. Пример:
Метод третий: функции CharToOem и OemToChar Две API-шные функции:
В качестве первого параметра функции принимают С-строчку, которую преобразуем, в качестве второго - строчку, в которую будет помещен результат преобразования. Если эти функции используются как ANSI-функции, то в качестве обоих параметров можно передавать одну и ту же строку. В таком случае переданная функции строчка просто преобразуется в нужную нам кодировку (без какого-либо буфера). Есть еще пара вариантов:
Работают также как и CharToOem/OemToChar, с той лишь разницей, что в качестве третьего параметра принимают количество символов в строке, которые надо преобразовать.
Эти функции преобразуют строчку из ANSI в OEM и наоборот. Это значит, что нам вообще не надо мучаться с номерами кодовых страниц и т.п. Но проблема в том, что преобразуют они лишь одну строчку. А сколько нам в программе может понадобиться выводить и вводить из консоли строчки - неизвестно, но каждую строчку (русскую) надо преобразовывать, следовательно, каждый раз при этом надо будет вызывать эти функции. Получается код, довольно захламленный постоянными вызовами одних и тех же функций. Но что поделаешь… Чтобы избежать неудобств при использовании таких функций, можете, скажем, написать свой собственный класс, который будет чем-то вроде оболочки для выполнения этих операций. Например, класс, в котором будут перегружены операторы ввода (operator >>) и вывода (operator <<) таким образом, чтобы перед самим вводом/выводом выполнять необходимое преобразование. Чтобы для практики такой класс имел значение и был полезен, надо постараться - учесть всевозможные переполнения буфера, преобразования типов и т.д. и т.п. В общем, безопасность и функциональность - очень важны. А если вдруг захочется попробовать создать класс, производный от iostream, учтите, что в нём виртуальных функций нет. На мой взгляд, для теоретических знаний языка С++ это может быть полезно, но для практики проще (а пожалуй и лучше) просто явно вызывать функцию
Пример:
Метод четвертый: CString::AnsiToOem и CString::OemToANSI В MFC для работы со строками есть специальный класс CString. И у этого замечательного класса есть кроме других два метода:
Эти функции осуществляют необходимое преобразование над объектом класса CString. Класс CString хорош, с ним очень удобно работать и уж лучше всегда по мере возможности использовать его вместо строк стиля С (массива символов). Хотя можно, конечно, и шаблон string из STL (Standard template library - Стандартная Библиотека Шаблонов, она входит в стандартную библиотеку). Пример:
Это сообщение отредактировал(а) papam - 29.12.2007, 18:28 --------------------
No Fucking Future |
||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||
nickless |
|
|||
![]() Гентозавр ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2976 Регистрация: 29.8.2005 Где: Germany Репутация: 2 Всего: 181 |
Предлагаю написать в начале статьи, что речь идёт исключительно о windows, а то в линуксе, благодаря utf-8, прекрасно работают программки вроде
![]() -------------------- ![]() Real men don't use backups, they post their stuff on a public ftp server and let the rest of the world make copies - Linus Torvalds |
|||
|
||||
papam |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 104 Регистрация: 2.2.2006 Где: Украина::Запорожь е Репутация: 2 Всего: 4 |
Можно прикрепить эти примеры к статье, тут 3 скриншота к каждому методу,я забыл, прошу прощения
Это сообщение отредактировал(а) papam - 26.12.2007, 20:05 Присоединённый файл ( Кол-во скачиваний: 54 ) ![]() --------------------
No Fucking Future |
|||
|
||||
Dov |
|
|||
![]() аСинизатор ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1721 Регистрация: 10.5.2003 Где: Эрец-Исраэль Репутация: 11 Всего: 88 |
papam, кроме тех требований, которые ты упомянул, есть ещё, как минимум, два, которые ты не назвал, а именно: 1. Нужно использовать оконный режим, а не полноэкранный. 2. Нужно установить в свойствах окна шрифт Lucida Console. Может быть по-этому у тебя и не работало на других машинах. ![]() -------------------- Тут вечности запах томительный, И свежие фрукты дешевые, А климат у нас – изумительный, И только соседи – #уевые. Игорь Губерман. |
|||
|
||||
archimed7592 |
|
|||
![]() Архимед ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2531 Регистрация: 12.6.2004 Где: Moscow Репутация: 6 Всего: 93 |
papam, всё пока не читал - только пробежался.
Первые претензии: 1. Убрать из текста слова "отродья", "ни хрена", "мессага", "фига" и пр. Воспользоваться более культурными синонимами. Короче говоря, переработать текст, чтобы его можно было "отдавать в печать". 1.1. Исправить множественные опечатки(в т.ч., часто встречающийся "<" вместо "<"). 2. Оформить все строки кода(в т.ч. прототипы ф-ций) в тэги code. 3. Я примеры не смотрел, но, если они не большие, то добавить их в текст, причём не просто в конце, а к каждому методу отдельно. All, просьба оценить техническую корректность текста, причём, подойти к этому нужно настолько критично, насколько это возможно ![]() -------------------- If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas. © George Bernard Shaw |
|||
|
||||
archimed7592 |
|
|||
![]() Архимед ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2531 Регистрация: 12.6.2004 Где: Moscow Репутация: 6 Всего: 93 |
papam, как я вижу, ты немного подредактировал текст.
Смотри, если человек приходит с вопросом "почему у меня каракули в программе", то, очевидно, что он умеет создавать проект в своей любимой IDE(которая не обязательно будет MSVC), так что, думаю, что нужно убрать подробности о том, как создавать проект, какие строки и откуда нужно удалять и т.п. Схема должна быть такой: описание метода, потом слова "Пример:" и сам пример, обрамлённый тегом code. Причём, обязательно откорректировать примеры, убрав оттуда MS-специфичные вещи, аля _t, TCHAR и пр.(если метод не ориентирован исключительно на MSVC). main не должна принимать аргументы, если они ей не нужны. -------------------- If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas. © George Bernard Shaw |
|||
|
||||
papam |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 104 Регистрация: 2.2.2006 Где: Украина::Запорожь е Репутация: 2 Всего: 4 |
archimed7592, историю убрать?
--------------------
No Fucking Future |
|||
|
||||
archimed7592 |
|
|||
![]() Архимед ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2531 Регистрация: 12.6.2004 Где: Moscow Репутация: 6 Всего: 93 |
papam, я пока подробно не читал. Не знаю. После НГ будем более подробно разбираться. Сейчас, к сожалению, времени совсем нет.
-------------------- If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas. © George Bernard Shaw |
|||
|
||||
zkv |
|
|||
![]() ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2133 Регистрация: 23.7.2006 Где: Санкт-Петербург Репутация: нет Всего: 92 |
||||
|
||||
zkv |
|
|||
![]() ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2133 Регистрация: 23.7.2006 Где: Санкт-Петербург Репутация: нет Всего: 92 |
да про это стоит упомянуть. для сведения, посмотри что пишет уважаемый baldina (помню кто-то использовал преобразование к unsigned в качестве решения вопроса) решение с локалью думаю стоит вынести в первую очередь, и упомянуть хотя-бы о существовании std::locale а такие вещи: окучить бы не мешало.. разве локали можно использовать только вместе с юникодом? Это сообщение отредактировал(а) zkv - 27.12.2007, 23:57 |
|||
|
||||
Winprogrammer |
|
||||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 141 Регистрация: 23.3.2006 Где: ::Россия.РСО-Алан ия.Владикавка Репутация: нет Всего: нет |
papam,
опиши все параметры. Они могут пригодиться.
Сперва опиши в чем заключается второй метод. А потом уже приступай к описанию функций, как ты это сделал в первом методе. Третий и четвертый методы имеют тот же недостаток оформления - нет описания. Это функции какого API ???? API - это Application Programming Interface. Как таковых API много. Для опытного человека понятно, что это WinAPI. А для новичка - это тёмные дебри. Используй более оффициальный язык. ЗЫ: В принципе статья - отличная! только ее надо "вылизать"! ;) Вот пока все, что могу сказать. Но над статьей надо еще работать... работать... и работать... ![]() --------------------
Я не понял Вашего вопроса, но я Вам на него отвечу…----------- Uploading файлов без гемороя - это просто!!! Winprogrammer.ifolder.ru |
||||
|
|||||
archimed7592 |
|
||||||||||
![]() Архимед ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2531 Регистрация: 12.6.2004 Где: Moscow Репутация: 6 Всего: 93 |
Что ж. Начну, наверное, с этой статьи. А точнее с первого метода(локаль).
Сразу предупрежу, что, даже если покажется, что я как-то грубо высказываюсь - это не означает, что я к Вам плохо отношусь. Можете считать, что я выражаю мысли новичка, который читает Вашу статью ![]()
OEM - это что за кодировка такая? Неплохо было бы упомянуть. ANSI - это что за кодировка? А Unicode мы в этой статье не рассматриваем? Какая ещё программа? Какой файл? Зачем ругаться? О чём вообще речь?
Отлично, а в каком заголовочном файле эта ф-ция объявлена?
Ммм. Не обязательно каждое слово оформлять в тэг code. Можно было бы либо просто не оформлять никак, либо выделить моноширинным шрифтом(предпочтительнее). К примеру так: category – категория (тип) изменения локали. [font=courier]category[/font] – категория (тип) изменения локали. Очень интересно, хорошо бы ещё понять к чему мне нужно было читать этот абзац. А ещё лучше - понять бы к чему нужен был предыдущий абзац между сигнатурой ф-ции и описанием её параметров. В какой программе? Вы о чём? Кем кем? Литералом? А это кто?
Хнык-хнык. А мой компилятор, говорит, что не знает о такой ф-ции :'(.
А зачем нам юникод сдался? Мне что, из-за этих каракуль всю программу под юникод переписывать? Я что-то не понял - пример для Си или для С++? Хто есть my_codecvt? Мой компилятор отказывается это компилировать. Хнык-хнык. Теперь в общем и целом: повествование оформленно как описание примера. Пример почему-то идёт после самого описания. Зачем-то смешаны и Си и С++. Пожелания(кроме процитированных багов): 1. перед самими методами в двух словах написать откуда вообще взялась проблема. 2. перед методами перечислить список методов с очень кратким описанием. 3. метод: сначала описание метода как такого, потом пример, потом описание примера. 4. в примерах не должно быть ничего лишнего(зачем там вообще понадобились файлы? а юникод?) -------------------- If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas. © George Bernard Shaw |
||||||||||
|
|||||||||||
papam |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 104 Регистрация: 2.2.2006 Где: Украина::Запорожь е Репутация: 2 Всего: 4 |
archimed7592,завтра постараюсь исправить все.
--------------------
No Fucking Future |
|||
|
||||
archimed7592 |
|
|||
![]() Архимед ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2531 Регистрация: 12.6.2004 Где: Moscow Репутация: 6 Всего: 93 |
papam, как дела со статьей продвигаются?
![]() -------------------- If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas. © George Bernard Shaw |
|||
|
||||
archimed7592 |
|
|||
![]() Архимед ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2531 Регистрация: 12.6.2004 Где: Moscow Репутация: 6 Всего: 93 |
-------------------- If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas. © George Bernard Shaw |
|||
|
||||
![]() ![]() ![]() |
Правила форума "C/C++: Для новичков" | |
|
Запрещается! 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa. |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Для новичков | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |