Модераторы: feodorv, GremlinProg, xvr, Fixin
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Не выводит UNICODE символы (кириллица) 
V
    Опции темы
sosedywka
Дата 4.6.2011, 17:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 7
Регистрация: 30.5.2011

Репутация: нет
Всего: нет



День добрый! Помогите, пожалуйста, разобраться с проблемой:
После нажатия кнопки в меню, должно открываться диалоговое окно "открытие файла", должен выбираться файл и читаться. Но если в файле находятся символы кириллицы, он выводит ерунду. Проверяю MessageBox'ом и Edit'ом
вот код:
Код

case MI_OPEN:
            
            memset(&nCnt,0,sizeof(nCnt));
            memset(&szBuffer,0,sizeof(szBuffer));
            memset(&ofn,0,sizeof(ofn));

            ofn.lStructSize = sizeof(OPENFILENAME);
            ofn.hwndOwner = hwnd;
            ofn.lpstrFilter = szFilter;
            ofn.lpstrFile = LPWSTR(szFile);
            ofn.nMaxFile = sizeof(szFile);
            ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
                        
            if(GetOpenFileName(&ofn))
            {
                HANDLE hFile = CreateFile(LPCWSTR(szFile), GENERIC_READ, 0, 0, OPEN_EXISTING, 0, NULL);
                if (hFile == INVALID_HANDLE_VALUE)
                {
                    wchar_t szFileError[] = _T("Error!");
                    MessageBox(NULL, szFileError, _T("info"), MB_OK);
                    break;
                }

                wchar_t szFileOk[] = _T("Ok!");
                MessageBox(NULL, szFileOk, _T("info"), MB_OK);

                ReadFile(hFile, szBuffer, 500, &nCnt, NULL);

                WCHAR* szTempBuffer = new WCHAR[strlen(szBuffer) + 1];
                int nCharsBuffer = ::MultiByteToWideChar(1251, 0, szBuffer, -1, szTempBuffer, strlen(szBuffer) + 1);
                MessageBox(NULL, szTempBuffer, _T("Buffer"), MB_OK); //Выводит чушь, если символы на кириллице

                HWND hwndEditText = GetDlgItem(hwnd, IDC_EDIT1);
                SetWindowText(hwndEditText, LPCWSTR(szTempBuffer)); //Аналогично

                CloseHandle(hFile);
                bDataOk = TRUE;
                
            }
            break;


а также определение переменных:
Код

//для операций с файлом номинаций
wchar_t szFile[256]; //путь к файлу
char szBuffer[500]; //буфер для чтения из файла номинаций
BOOL bDataOk = FALSE; // Флаг чтения из файла
OPENFILENAME ofn; //структура для чтения файла
wchar_t szFilter[] = _T("Файлы номинаций(*.txt)\0*.txt\0Все файлы(*.*)\0*.*\0"); // фильт
DWORD nCnt;


Добавлено через 6 минут
скрин вывода, скрин того, что должно выводиться прилагается.

Присоединённый файл ( Кол-во скачиваний: 12 )
Присоединённый файл  111.JPG 5,74 Kb
PM MAIL   Вверх
sosedywka
Дата 4.6.2011, 17:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 7
Регистрация: 30.5.2011

Репутация: нет
Всего: нет



что должно выводиться:

Присоединённый файл ( Кол-во скачиваний: 18 )
Присоединённый файл  123123.JPG 9,13 Kb
PM MAIL   Вверх
volatile
Дата 4.6.2011, 23:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

Репутация: 13
Всего: 85



sosedywka, у вас программа нормальная (ну смотрел правда по-диагонали) 
У вас дело в другом. Файл который вы читаете должен быть в win-1251.
А он у вас в UTF-8. (это я могу сказать точно, вижу просто по символам на картинке).
Так что в блокноте сохраните ваш вайл в win-1251 (там он кажется ANSI называется).

PM MAIL   Вверх
sosedywka
Дата 5.6.2011, 16:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 7
Регистрация: 30.5.2011

Репутация: нет
Всего: нет



Цитата(volatile @ 4.6.2011,  23:23)
sosedywka, у вас программа нормальная (ну смотрел правда по-диагонали) 
У вас дело в другом. Файл который вы читаете должен быть в win-1251.
А он у вас в UTF-8. (это я могу сказать точно, вижу просто по символам на картинке).
Так что в блокноте сохраните ваш вайл в win-1251 (там он кажется ANSI называется).

volatile, спасибо, вы правы, так и есть. В кодировке ANSI, все выводит верно, без малейших косяков. Но можно как то абстрагироваться от кодировки файла? Или, скажем проверять кодировку до чтения, а затем судя по ней читать в разные форматы (или разными функциями)?
(Дело в том, что файлы не мои, и я не могу изменять их. Иначе, когда дело дойдет до сдачи, там эти косяки всплывут smile )

На MSDN нашел вот такое описание MessageBox:
Unicode and ANSI names    MessageBoxW (Unicode) and MessageBoxA (ANSI)
вот ссылка:MSDN MessageBox Function
Это единственное, что там сказано про эти функции, поэтому действовал методом тыка:

Пробовал следующее:
Код

MessageBoxW(NULL, szTempBuffer, _T("MessageBoxW:Buffer Wide Char"), MB_OK);
MessageBoxW(NULL, LPCWSTR(szBuffer), _T("MessageBoxW:Buffer Char"), MB_OK); 
MessageBoxA(NULL, LPCSTR(szTempBuffer), "MessageBoxA:Buffer Wide Char", MB_OK); 
MessageBoxA(NULL, szBuffer, "MessageBoxA:Buffer Char", MB_OK);

где переменные:
char szBuffer[500];
wchar_t szTempBuffer[500];

2,3 MessageBox'ы не выводят даже латинские символы(что, в принципе, логично),
1,4 MessageBox'ы выводят все как раньше, т.е. кирилицу не воспринимают.

Это сообщение отредактировал(а) sosedywka - 5.6.2011, 16:40
PM MAIL   Вверх
volatile
Дата 6.6.2011, 01:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

Репутация: 13
Всего: 85



Цитата(sosedywka @  5.6.2011,  16:29 Найти цитируемый пост)
Но можно как то абстрагироваться от кодировки файла? Или, скажем проверять кодировку до чтения, а затем судя по ней читать в разные форматы (или разными функциями)?

В силу сложившихся обстоятельств, русских кодировок, больше чем можно себе представить. 
Поддерживать все - задача практически не решаемая.
Кроме того, нельзя определить однозначно кодировку файла, если она не известна.
Есть правда утилиты, определяющие кодировку по частоте встречаемых символов, но для их работы нужно чтобы текст был достаточно большим. Да и все равно это все очень не надежно. В вашем случае, по 2-ум словам, да еще вперемежку с английскими...  smile 

Короче, нужно чтобы кодировка файла, была определенная.
Если входные файлы в кодировке UTF8, нужно вызывать конвертор в юникод так:
Код

   int nCharsBuffer = ::MultiByteToWideChar(CP_UTF8, 0, szBuffer, -1, szTempBuffer, strlen(szBuffer) + 1);

Но эта функция не удаляет BOM, это вам нужно будет сделать вручную (для UTF8 BOM = 0xef, 0xbb, 0xbf).
Но учтите что BOM'а может и не быть, так что сначала нужно проверить. 

Да и кроме того, по секрету скажу, что UTF8, не родной формат винды, и работает она с ним кривовато.

Добавлено через 1 минуту и 17 секунд
И еще, не нужно юзать MessageBoxW MessageBoxA, это не для этого.
используйте MessageBox
 smile 
PM MAIL   Вверх
GremlinProg
Дата 6.6.2011, 06:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



грубейшая ошибка, нельзя так делать:
Цитата(sosedywka @  4.6.2011,  19:05 Найти цитируемый пост)
ofn.lpstrFile = LPWSTR(szFile);

с такими темпами, поместим ее в правила, т.к. ответ следует автоматический - неправильная работа с кодировками,
от такого преобразования строка не будет преобразована в юникод,
она так только будет обзываться, что еще больше запутает логику программы

от кодировки файла не абстрагироваться, но можно дать возможность пользователю подобрать ее самому, если нет бомов (и даже если есть)


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
sosedywka
Дата 6.6.2011, 22:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 7
Регистрация: 30.5.2011

Репутация: нет
Всего: нет



Изменил кодировку блокнота на ANSI.

GremlinProg, Это я случайно оставил, когда пытался присвоить ofn.lpstrFile строку char. Потом тип изменил, а LPWSTR осталось. Спасибо, буду внимательней.

volatile, Спасибо, я ознакомлюсь с функцией MultiByteToWideChar.

Всем спасибо за участие smile
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема »


 




[ Время генерации скрипта: 0.0981 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.