Модераторы: bsa
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> преобразование ascii в unicode 
:(
    Опции темы
nitrexin
Дата 10.12.2008, 22:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Пишу курсовик, и не знаю что делать дальше. Задание: открыть текстовый файл, и преобразовать из dos кодировки в unicode. При этом есть условие, не использовать стороних библиотек.
У меня не получается открыть текстовый файл, и прочесть его в массив, а если использовать строку в самом массиве, то на вывод она идет без слова в dos кодировке. Одним словом нужна помощь smile
Код

#include <stdio.h>
#include <stdlib.h>
unsigned char* ASCIItoUNICODE (unsigned char ch);
unsigned int* ConvertString (unsigned char *string);
void UnicodePrint(unsigned int* Message);
//прототипы

int main()
{

FILE *stream;
//пытаемся открыть текстовый файл
if((stream = fopen("text.txt","rb")) == NULL){ printf("! ");return;}
fread(&c,2,1,stream);
//и прочесть его в массив text
fread(text,2,c,stream); 
unsigned char text[100];
//unsigned char text[] = "привет,world" ;
//привет написано в dos кодировке
unsigned int *UnMess;
printf("Content-type: text/plain\n\n\n");

UnMess = ConvertString(text);
UnicodePrint(UnMess);
fclose(stream);

}

unsigned char* ASCIItoUNICODE (unsigned char ch)
{
unsigned char Val[2];
if ((ch < 192)&&(ch != 168)&&(ch != 184)) {Val[0] = 0; Val[1] = ch; return Val;}
if (ch == 168) {Val[0] = 208; Val[1] = 129; return Val;}
if (ch == 184) {Val[0] = 209; Val[1] = 145; return Val;}
if (ch < 240) {Val[0] = 208; Val[1] = ch-48; return Val;}
if (ch < 249) {Val[0] = 209; Val[1] = ch-112; return Val;}
}
unsigned int* ConvertString (unsigned char *string)
{
unsigned int size=0, *NewString;
unsigned char* Uni;
while (string[size++]!=0);
NewString = (unsigned int*)malloc(sizeof(unsigned int)*2*size-1);
NewString[0]=2*size-1;
size=0;
while (string[size]!=0)
{
Uni = ASCIItoUNICODE(string[size]);
NewString[2*size+1]=Uni[0];
NewString[2*size+2]=Uni[1];
size++;
}
return NewString;
}

void UnicodePrint(unsigned int* Message)
{
int size, i;

size=Message[0];
if (Message[1] == 0) i=2;
else i=1;

while (i<size)
{
printf("%C",Message[i]);
i++;
}
}







Это сообщение отредактировал(а) nitrexin - 10.12.2008, 22:30
PM MAIL WWW Jabber   Вверх
Alca
Дата 10.12.2008, 23:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Код

//---------------------------------------------------------------------------
std::wstring wsASCIIToUnicode(const std::string &csSrc) {
    std::wstring wsRes;
    for (size_t i = 0; i < csSrc.length(); ++ i) {
        wsRes += static_cast<wchar_t>(csSrc[i]);
    }
        
    return wsRes;
}
//---------------------------------------------------------------------------
std::string sUnicodeToASCII(const std::wstring &cwsSrc) {
    std::string sRes;
    for (size_t i = 0; i < cwsSrc.length(); ++ i)
        sRes += static_cast<char>(cwsSrc[i]);
        
    return sRes;
}
//---------------------------------------------------------------------------



--------------------
PM WWW ICQ Skype Jabber   Вверх
vinter
Дата 11.12.2008, 07:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


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

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



Alca, жжошь  smile

Добавлено через 1 минуту и 38 секунд
Цитата(nitrexin @  10.12.2008,  23:17 Найти цитируемый пост)
При этом есть условие, не использовать стороних библиотек.

winapi тоже сторонней считаем?


--------------------
Мой блог
PM MAIL WWW   Вверх
bsa
Дата 11.12.2008, 13:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

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



Цитата(nitrexin @ 10.12.2008,  22:17)
У меня не получается открыть текстовый файл, и прочесть его в массив

На С++ это выглядит так:
Код
#include <fstream>
#include <vector>
#include <algorithm>
#include <iterator>
#include <iostream>

int main()
{
   std::vector<char> array;   //создаем пустой массив
   std::ifstream file("file.txt"); //открываем файл
   file.unsetf(std::ios::skipws); //не пропускать пробельные символы
   //и загружаем его в массив
   std::copy(std::istream_iterator<char>(file), std::istream_iterator<char>(), std::back_inserter(array));
   //а теперь выводим содержимое массива на экран
   std::copy(array.begin(), array.end(), std::ostream_iterator<char>(std::cout));
   return 0;
}
А на Си так:
Код
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>

int main()
{
   char *array;
   size_t size;
   int f = open("file.txt", O_RDONLY);   //открываем файл
   if (f < 0)
      return 1; //ошибка
   size = lseek(f, 0, SEEK_END); //перемещаем позицию в конец файла и определяем текущую позицию в файле (размер файла, так как она в конце его)
   array = (char*)malloc(size + 1); //выделяем память
   lseek(f, 0, SEEK_SET); //возвращаем позицию файла в начало
   size = read(f, array, size); //читаем файл в массив
   array[size] = '\0'; //ставим символ конца строки
   printf("%s\n", array);  //выводим на экран
   free(array); //освобождаем память
   close(f);
   return 0;
}



Это сообщение отредактировал(а) bsa - 11.12.2008, 13:29
PM   Вверх
Alca
Дата 11.12.2008, 13:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата

жжошь

Не понял.


--------------------
PM WWW ICQ Skype Jabber   Вверх
Fazil6
Дата 11.12.2008, 13:54 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Цитата(Alca @  11.12.2008,  13:22 Найти цитируемый пост)
Не понял. 

бред ты написал. Что тут непонятного?
PM MAIL   Вверх
bsa
Дата 11.12.2008, 14:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

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



Цитата(Fazil6 @ 11.12.2008,  13:54)
Цитата(Alca @  11.12.2008,  13:22 Найти цитируемый пост)
Не понял. 

бред ты написал. Что тут непонятного?

подтверждаю. Так как в юникоде старший байт русских букв точно отличается от нулевого. На счет английских не скажу.
описание юникода
PM   Вверх
Alca
Дата 11.12.2008, 14:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



А как правильно?


--------------------
PM WWW ICQ Skype Jabber   Вверх
bsa
Дата 11.12.2008, 14:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

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



вот здесь дана таблица соответствия: http://ru.wikipedia.org/wiki/Альтернативная_кодировка
PM   Вверх
Alca
Дата 11.12.2008, 14:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



А кодом?


--------------------
PM WWW ICQ Skype Jabber   Вверх
bsa
Дата 11.12.2008, 18:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

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



Цитата(Alca @ 11.12.2008,  14:53)
А кодом?

http://ftp.gnu.org/pub/gnu/libiconv/libiconv-1.12.tar.gz
PM   Вверх
Alca
Дата 19.12.2008, 12:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Q: How to convert between ANSI and UNICODE strings?

A: The quick and dirty way

This way of working is correct for codepages that are single-byte and Unicode strings that are UCS2. This applies to most cases, but if your program should run correctly on Japanese, Chinese, Taiwanese and other systems which have DBCS codepages then use the "correct way" described further below.

ANSI to UNICODE:

The conversion is done using the 'MultiByteToWideChar()' function:

Код

char *ansistr = "Hello";
int a = lstrlenA(ansistr);
BSTR unicodestr = SysAllocStringLen(NULL, a);
::MultiByteToWideChar(CP_ACP, 0, ansistr, a, unicodestr, a);
//... when done, free the BSTR
::SysFreeString(unicodestr);
UNICODE to ANSI:


The UNICODE string mostly is returned by some COM function, like this one:

Код

HRESULT SomeCOMFunction(BSTR *bstr)
{
   *bstr = ::SysAllocString(L"Hello");
   return S_OK;
}


The conversion is done using the 'WideCharToMultiByte()' function:

Код

BSTR unicodestr = 0;
SomeCOMFunction(&unicodestr);
int a = SysStringLen(unicodestr)+1;
char *ansistr = new char[a];
::WideCharToMultiByte(CP_ACP, 
                        0, 
                        unicodestr, 
                        -1, 
                        ansistr, 
                        a, 
                        NULL, 
                        NULL);
//...use the strings, then free their memory:
delete[] ansistr;
::SysFreeString(unicodestr);


The correct way

If you want to handle DBCS codepages and UTF-16 Unicode strings then you should do things this way. The idea is to call 'MultiByteToWideChar()' resp. 'WideCharToMultiByte()' twice. First you get the length of the result, then you allocate the resulting string and call it again to convert.

ANSI to Unicode
Код

char *ansistr = "Hello"
int lenA = lstrlenA(ansistr);
int lenW;
BSTR unicodestr;

lenW = ::MultiByteToWideChar(CP_ACP, 0, ansistr, lenA, 0, 0);
if (lenW > 0)
{
  // Check whether conversion was successful
  unicodestr = ::SysAllocStringLen(0, lenW);
  ::MultiByteToWideChar(CP_ACP, 0, ansistr, lenA, unicodestr, lenW);
}
else
{
  // handle the error
}

// when done, free the BSTR
::SysFreeString(unicodestr);


Unicode to ANSI
Код

BSTR unicodestr = 0;
char *ansistr;
SomeCOMFunction(&unicodestr);
int lenW = ::SysStringLen(unicodestr);
int lenA = ::WideCharToMultiByte(CP_ACP, 0, unicodestr, lenW, 0, 0, NULL, NULL);
if (lenA > 0)
{
  ansistr = new char[lenA + 1]; // allocate a final null terminator as well
::WideCharToMultiByte(CP_ACP, 0, unicodestr, lenW, ansistr, lenA, NULL, NULL);
  ansistr[lenA] = 0; // Set the null terminator yourself
}
else
{
  // handle the error
}

//...use the strings, then free their memory:
delete[] ansistr;
::SysFreeString(unicodestr);


Это сообщение отредактировал(а) Alca - 19.12.2008, 12:49


--------------------
PM WWW ICQ Skype Jabber   Вверх
bsa
Дата 19.12.2008, 13:05 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

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



Alca, доктор, доктор, что мне делать?!? У меня нет функций MultiByteToWideChar и WideCharToMultiByte. Моя ОС (linux, кстати) о них ничего не знает (wine не предлагать).
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

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


 




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


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

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