Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Не получается создать файл с Unicode  (Прочитано 9351 раз)
0 Пользователей и 1 Гость смотрят эту тему.
tumanovalex
Помогающий

ru
Offline Offline

« : 09-02-2009 03:58 » 

Мне нужно создать файл с нужным повторением заданных букв Юникода.
unsigned char   s1[2] = "А" , s2[2] = "Б";
HANDLE pwfile;
WCHAR *ptr, us1[2], us2[2];
br = 0;
ns1 = 2; // количество повторов 1 символа Юникода
ns2 = 3; // количество повторов 2 символа Юникода
ns = ns1 + ns2;
nbyte = 10; // количество записываемых символов Юникода
MultiByteToWideChar(CP_ACP, 0, s1, 1, us1, 1);
MultiByteToWideChar(CP_ACP, 0, s2, 1, us2, 1);
ptr =  (WCHAR*) calloc(nbyte, sizeof(WCHAR));
wmemset(ptr, us1, nbyte);
for(i = ns1; i < nbyte; i+=ns) {
  for(j = 0; j < ns2; j++) {
   *(ptr + i + j)   = us2;
  } // for j
} //for i
pwfile = CreateFile("ЗнакиЮникод.txt", GENERIC_WRITE , 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
WriteFile(pwfile, ptr, nbyte*sizeof(WCHAR), &br, NULL);
CloseHandle(pwfile);
В результате получается ерунда. Подскажите, пожалуйста, в чем ошибка?

* Learning.zip (0.67 Кб - загружено 952 раз.)
Записан
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #1 : 09-02-2009 05:36 » 

ужас.
1. раскажи какое задание
2. объясни хотябы самому себе, что происходит в каждой строчке и зачем оно надо.
3. В чём разница между "А" и L"А"?
4. Почему сразу нельзя писать в файл?
5. Почему не пользуешься C++? Зачем тут WinAPI?
6. Что за паскалевский стиль? Сначла всё обявить, а потом использовать? Бррррррр
« Последнее редактирование: 09-02-2009 05:39 от LogRus » Записан

Странно всё это....
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #2 : 09-02-2009 07:13 » 

После некоторого ковыряния.
Код:
int _tmain(int argc, _TCHAR* argv[])
{
const wchar_t a[] = L"А";
const wchar_t b[] = L"Б";
size_t a_count = 2;
size_t b_count = 3;

std::wofstream ofs("UniChars.txt");
ofs.imbue(std::locale(argv[1]));

std::ofstream ofbs("UniChars.bin", std::ios::binary);

for (size_t i = 0; b_count != i; ++i)
{
for (size_t j = 0; a_count != j; ++j)
{
ofs << a;
ofbs.write(reinterpret_cast<const char*>(a), sizeof(wchar_t));
}
ofs << b;
ofbs.write(reinterpret_cast<const char*>(b), sizeof(wchar_t));
}

return 0;
}

два способа вывода:
1. Это использовать локаль, но тут один минус, далеко не всегда UCS или UTF пооддержаны в системе, как следствие wchar_t ковертится только в 866 или 1251, под виндой. На линуксе набор по шире, но тоже не сильно спасает.
2. Сброс широких символов прямо в файл, как есть.
Записан

Странно всё это....
tumanovalex
Помогающий

ru
Offline Offline

« Ответ #3 : 09-02-2009 10:06 » 

Спасибо за ответ. В поставленной мне задаче следующие условия:
1. Размеры буфера не фиксированы, могут изменяться в широких пределах.
2. Буфер может заполняться как кусками текста, так и фиксированным набором алфавита. Фиксированный алфавит задается символами ANSI, а в буфер нужно разместить символы в юникоде. Эту задачу я в упрощенном виде и попробовал запрограммировать (раньше с юникодом вообще никаких дел не имел).
3. Запись на диск должна осуществляться после заполнения буфера.
4. Язык - только С.
Почему именно так, я не знаю, но задание такое. Попробую переложить Ваш код на С.
Записан
Вад
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #4 : 09-02-2009 10:13 » 

tumanovalex, на C придётся изрядно перелопачивать Улыбаюсь
А почему у тебя 1 символ в юникод конвертируется?
int MultiByteToWideChar(
  UINT CodePage,
  DWORD dwFlags,
  LPCSTR lpMultiByteStr,
  int cbMultiByte,
  LPWSTR lpWideCharStr,
  int cchWideChar
);

// ...
 lpMultiByteStr
    [in] Pointer to the character string to be converted.

cbMultiByte
    [in] Size, in bytes, of the string pointed to by the lpMultiByteStr parameter. If this value is –1, the string is assumed to be null terminated and the length is calculated automatically.

lpWideCharStr
    [out] Pointer to a buffer that receives the translated string.

cchWideChar
    [in] Size, in wide characters, of the buffer pointed to by the lpWideCharStr parameter.
    If this value is zero, the function returns the required buffer size, in wide characters, and makes no use of the lpWideCharStr buffer.

Кстати, он корректно вообще преобразуется? То есть, сама функция отрабатывает как надо, и только в файл не то пишется?
Записан
tumanovalex
Помогающий

ru
Offline Offline

« Ответ #5 : 10-02-2009 06:26 » 

Спасибо за ответ, Вад. Не в первый раз Вы мне помогаете. Если записывать только символы после преобраования по отдельности, то все получается правильно. При заполнении буфера правильно записывается в файл при таком изменении кода:
wmemset(ptr, us1[0], nbyte*sizeof(WCHAR));
for(i = ns1; i < nbyte; i+=ns) {
  for(j = 0; j < ns2; j++) {
    if(i + j  > nbyte - 1) goto m1;
   *(ptr + i + j)   = us2[0];
  } // for j
} //for i
Теперь бы хотел решить ту же задачу с использованием стандартной библиотеки С для преобразования ANSI в Unicode. Подскажите, пожалуйста, как это можно сделать.
« Последнее редактирование: 10-02-2009 06:29 от tumanovalex » Записан
Вад
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #6 : 10-02-2009 06:40 » 

В CRT есть функция mbstowcs.
Записан
tumanovalex
Помогающий

ru
Offline Offline

« Ответ #7 : 10-02-2009 06:46 » 

Спасибо большое, попробую.
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines