Есть некая программа на C++, в нем из файла считывается и преобразуется строка в формате string, как можно ее из cp866 преобразовать в cp1251?
Средство должно быть кросплатформенное и собираться под MinGW.
[Решено]C++ перекодировка из cp866 в cp1251 (Перекодировка строки или файла из cp866 в cp1251)
Модератор: Модераторы разделов
-
- Сообщения: 480
- Статус: Keep It Simple, Stupid
- ОС: RFRemix 14
[Решено]C++ перекодировка из cp866 в cp1251
I learned something today
-
- Бывший модератор
- Сообщения: 4038
- Статус: Искусственный интеллект (pre-alpha)
- ОС: Debian GNU/Linux
Re: [Решено]C++ перекодировка из cp866 в cp1251
Конкретно из cp866 в cp1251 можно обойтись элементарным массивом на 256 char'ов и функцией:
Код: Выделить всё
char translate(char const* table, char c) {
return table[(unsigned char)c];
}
Мои розовые очки
Спасибо сказали:
-
- Сообщения: 3321
- Статус: Красный глаз тролля
- ОС: ArchLinux
Re: [Решено]C++ перекодировка из cp866 в cp1251
Пример на С (правда, декодирует в КОИ-8):
Но лучше подключить enca.
Код: Выделить всё
#include <stdio.h>
#include <string.h>
unsigned char c[3][128]={
"─│┌┐└┘├┤┬┴┼▀▄█▌▐░▒▓⌠■∙√≈≤≥ ⌡°²·÷═║╒ё╓╔╕╖╗╘╙╚╛╜╝╞╟╠╡Ё╢╣╤╥╦╧╨╩╪╫╬©юабцдефгхийклмнопярстужвьызшэщчъЮАБЦДЕФГХИЙКЛМНОПЯРСТУЖВЬЫЗШЭЩЧЪ",
"???????????????????????????????? ???????Ё©??????°??????·ё???????АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюя",
"АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмноп░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀рстуфхцчшщъыьэюяЁё??????°∙·√??■ "};
char encode(const int ch, const int i){ //returns encoding letter
char ret;
if (ch == 13) ret = 10;
else
if (ch < 128) ret = ch;
else
ret = c[i][ch%256 - 128];
return ret;
}
int recognize(FILE* f){ //asks to recognize encoding
char* ans=(char*) malloc(128);
int i,ch,ii;
if (f==NULL){
printf("Cannot open file\n");
exit(4);
}
printf("\n");
for (i=0; i<3; i++){
ch=fgetc(f);
ii=0;
while(ch != EOF){
if (ch>127){
++ii;
if (ii<256) putchar(encode(ch,i));
else
break;
}
ch=fgetc(f);
}
rewind(f);
printf("\n\nIs it right?[n]\n");
scanf("%s",ans);
if(strcmp(ans,"y")==0 || strcmp(ans,"yes")==0) return i;
}
printf("\n\t\t\tUndefined codepage!!!\n\n");
return 0;
}
int main(int argc, char** argv){
int x,i,l;
char name[128];
FILE *f, *f1, *f2;
if(argc<2){
printf("\nError! Need at least 1 argument!!!\n");
exit(1);
}
int global=0; //asks to recognize only once
if(strcmp(argv[1],"cp1251")==0 || strcmp(argv[1],"CP1251")==0){
--argc; ++argv;
global=1;
x=1;
}
if(strcmp(argv[1],"-r")==0 && global != 1){
printf("Recognize first file\n");
--argc; ++argv; //analog of shell's "shift"
global=1;
f=fopen(argv[1],"r");
x=recognize(f);
fclose(f);
}
for (i=1; i<argc; i++){
f=fopen(argv[i],"r");
if (global==0) x=recognize(f);
sprintf(name, "enc.%d", i);
f1=fopen("tmp_encode","w");
l=fgetc(f);
while(l!=EOF){
fputc(encode(l,x),f1); //this is encoding itself
l=fgetc(f);
}
fclose(f1);
fclose(f);
unlink(argv[i]);//rename tmp->argv[i]
if(link("tmp_encode",argv[i])<0)
printf("error moving file %s\n",argv[i]);
unlink("tmp_encode");
printf("File %s is done\n",argv[i]);
}
printf("\nAll files are processed!!!\n");
}
Но лучше подключить enca.
RTFM
-------
KOI8-R - патриотичная кодировка
-------
KOI8-R - патриотичная кодировка

Спасибо сказали:
-
- Сообщения: 480
- Статус: Keep It Simple, Stupid
- ОС: RFRemix 14
Re: [Решено]C++ перекодировка из cp866 в cp1251
Всем спасибо, понял в чем моя ошибка в решение этой задачи.
С самого начала я пытался найти готовую функцию или библиотеку работы с кодировками. Но как оказалось гораздо проще самому написать функцию преобразования кодировки.
Вот что получилось (возможно что то можно сделать кошернее, но опыта пока мало, так что что получилось то получилось.):
С самого начала я пытался найти готовую функцию или библиотеку работы с кодировками. Но как оказалось гораздо проще самому написать функцию преобразования кодировки.
Вот что получилось (возможно что то можно сделать кошернее, но опыта пока мало, так что что получилось то получилось.):
Код: Выделить всё
int n=0, simv_int; //Счетчик и цифровое значение символа
char simv; //Символ в char
string kon=" "; //Для сравнения в while, возможно можно убрать, но не знаю пока еще как
//строка храниться в типе string и после преобразования я в конец записываю символ пробела (чтобы видеть конец строки, в самой строке пробелов быть не может), хотя можно заменить на любой другой символ
while (str_kon[n]!=kon[0]){ //проверка конца строки
simv_int=str_kon[n]; //получение кода символа
simv=str_kon[n]; //преобразование символа в char
if (simv_int>-129 && simv_int<-80){ //проверка русских символов от "А" до "п"
str_kon_1251+=simv+64;
}
else if (simv_int>-33 && simv_int<-16){ //проверка русских символов от "р" до "я"
str_kon_1251+=simv+16;
}
else{ //остальные символы
str_kon_1251+=simv;
}
I learned something today
-
- Модератор
- Сообщения: 1786
- Статус: Матёрый линуксоид
- ОС: Debian testing/unstable
Re: [Решено]C++ перекодировка из cp866 в cp1251
man 3 iconv и далее по ссылкам.
Работа: Ubuntu 9.10
Дом: Debian testing/unstable и на всякий случай winxp в virtualbox.
Для разнообразия: моя домашняя страница -http://iportnov.ru
Дом: Debian testing/unstable и на всякий случай winxp в virtualbox.
Для разнообразия: моя домашняя страница -http://iportnov.ru
-
- Сообщения: 480
- Статус: Keep It Simple, Stupid
- ОС: RFRemix 14
Re: [Решено]C++ перекодировка из cp866 в cp1251
Рассматривал этот вариант, но слишком громоздко показалось.
I learned something today
-
- Сообщения: 1
- ОС: WinXP
Re: [Решено]C++ перекодировка из cp866 в cp1251
Что лучше переписать так
Код: Выделить всё
void cp866_cp1251( string &s ) {
for( char *c=(char*)s.c_str(); *c!=0; ++c ) {
if( *c>-129 && *c<-80 )
*c += 64;
else if( *c>-33 && *c<-16 )
*c += 16;
}
}
-
- Сообщения: 1685
- ОС: SuSe 10.2
Re: [Решено]C++ перекодировка из cp866 в cp1251
Qt низя пользовать по условиям задачи? QTextCodec все умеет и все может.
Любое конвертирование через юникод. Сначала в юникод потом куда угодно - в/из любой из полуторадесятков поддерживаемых кодировок.
Любое конвертирование через юникод. Сначала в юникод потом куда угодно - в/из любой из полуторадесятков поддерживаемых кодировок.
-
- Сообщения: 3321
- Статус: Красный глаз тролля
- ОС: ArchLinux
Re: [Решено]C++ перекодировка из cp866 в cp1251
Проще уж использовать libenca, чем мучиться с юникодом

RTFM
-------
KOI8-R - патриотичная кодировка
-------
KOI8-R - патриотичная кодировка

-
- Сообщения: 1685
- ОС: SuSe 10.2
Re: [Решено]C++ перекодировка из cp866 в cp1251
"Мучитьцца?" да прекратите вы. с Qt работать - одно удовольствие.