1

Привет всем.

Подскажите, пожалуйста, как сделать конвертацию из UTF8 в
CP1251 :rolleyes:

Подсмотрел програмку

...
         char buffout[50];
         char* bout = buffout;
         int nbbout = sizeof(buffout); 
...
         iconv_t cdout = iconv_open("CP1251","UTF8"); 
...
        char* code =  "$01T300TEXT\r\n";//codes[0];
    char* in = code;
    int numbin = strlen(code);
    printf("numbin -%d\n",numbin);
    memset(&buffout,0,sizeof(buffout));
        
    size_t res = iconv(cdout,&in,&numbin,&bout,&nbbout); 
    printf("%d\n",res);
    int siseofout = sizeof(bout);
    printf("sizeofout - %d\n",siseofout);
    size_t temp = nbbout;
    printf("in - %s\n",code);
    printf("bout - %d\n",temp);
               
...

Да только вот что-то  iconv не работает:
siseofout - 4 байта
nbbout -- 37
С чем может быть связано?

2

Конвертация iconv должна работать.
Показывай что и как ты конвертируешь, и какие ошибки при этом возникают.

3

обязательно на С? в шелле тоже есть iconv
iconv --help
man 3 iconv

Карусель разнесло по цепочке за час
Всех известий — конец
Да, весна началась!
(всё к лицу подлецу, как родному отцу, не рассказывай, батя, и так всё пройдёт)

4

Vascom пишет:

Конвертация iconv должна работать.
Показывай что и как ты конвертируешь, и какие ошибки при этом возникают.

- ?
Видно я что-то не понимаю... Я ведь привел часть кода проги...
Прогнал прогу через отладчик и strace
После

iconv_t cdout = iconv_open("CP1251","UTF8"); 

- код ошибки  - 0
После

size_t res = iconv(cdout,&in,&numbin,&bout,&nbbout); 

-
код ошибки  - 0, а strace, когда я отправляю bout на порт:

write(4,"\0\0\0..."...,37) = 37

5

DimonK, дайте полный код. я что, телепат?

Карусель разнесло по цепочке за час
Всех известий — конец
Да, весна началась!
(всё к лицу подлецу, как родному отцу, не рассказывай, батя, и так всё пройдёт)

6

Тогда тему в раздел Программирование надо отправить?

7

DimonK пишет:

- код ошибки  - 0

вы про что? про errno что-ли? дык там вообще всё что угодно может быть
дело в том, что errno устанавливается только после ошибке, а если всё хорошо, то там будет то-что было. в отличие от $?

вот вам пример (рабочий):
http://www.gnu.org/s/libc/manual/html_n … mples.html

Карусель разнесло по цепочке за час
Всех известий — конец
Да, весна началась!
(всё к лицу подлецу, как родному отцу, не рассказывай, батя, и так всё пройдёт)

8 (14.02.2011 10:23:47 отредактировано DimonK)

Привет всем
Спасибо,drBatty, за код smile

Суть проги такова: на устройстве сигнализации нажимается кнопка, я отсылаю команду codes[1] - чтение буфера клавы и считываю ответ
УС понимает CP1251 кодировку. Пробовал без перекодировки - ни чего. Решил что необходима кодировка...

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <err.h>
#include <termios.h>
#include <iconv.h>
#include <libintl.h>

int open_port(void);

char*codes[]=
{
    "$01T100TEXT\r\n", 
    "$01K\n", 
    "$01T\n\r" 
};

int main(int argc,char **argv)
{    
    char buffin[255];
    char buffout[50];
    
    char* bin = buffin;
    char* bout = buffout;
     
    int nbbin = sizeof(buffin);
    int nbbout = sizeof(buffout);
    
    iconv_t cdin  = iconv_open("UTF8","CP1251");
    iconv_t cdout = iconv_open("CP1251","UTF8");
    if ((cdin == (iconv_t)(-1)) && (cdout == (iconv_t)(-1)))
    err(1,"ICONV_OPEN");
        
    int fd=open_port();
        
    while(1)
    {
    int ch = getchar();
    if (ch == 27)
        break;
    
    char* code =  codes[0];
    char* in = code;
    int numbin = strlen(code);
    printf("numbin -%d\n",numbin);
    memset(&buffout,0,sizeof(buffout));
    
    size_t res = iconv(cdout,&in,&numbin,&bout,&nbbout); 
    printf("%d\n",res);
    int siseofout = sizeof(bout);
    printf("sizeofout - %d\n",siseofout);
    size_t temp = nbbout;
    printf("in - %s\n",code);
    printf("bout - %d\n",temp);
    
    int n = write(fd,bout,nbbout);
    if (n < 0)
        printf("write() failed!\n", stderr);
    else
        printf(" n= %d  \n",n);
        
    /*/------------------------------------------------
    //int k = read(fd,buffin,nbbin);
        
    char banswer[255];
    int nbansw = sizeof(banswer);
    int k = read(fd,buffin,nbbin);
    printf("%s\n",banswer);
    size_t d = strlen(buffin);
    res = iconv(cdin,&buffin,&d,&banswer,&nbansw);
    printf("\nbuf1-%s\n",banswer);
    */    
                
    }

    iconv_close(cdin);
    iconv_close(cdout);
    close(fd);
    return(0);
}
                                                        
int  open_port(void)
{
    int fd;
    fd = open("/dev/ttyS0", O_RDWR | O_NOCTTY |O_NONBLOCK);
    if (fd == -1)
        perror("open_port: Unable to open /dev/ttyS0 - "); 
    else
    {
    struct termios options; 
        tcgetattr(fd, &options);
        cfsetispeed(&options, B9600);
        cfsetospeed(&options, B9600);
        options.c_cflag &= ~PARENB; 
        options.c_cflag &= ~CSTOPB;
        options.c_cflag &= ~CSIZE;
        options.c_cflag |= CS8;
        tcsetattr(fd, TCSANOW, &options);
    }
    //fcntl(fd, F_SETFL, 0);
    return (fd);
}                

9

DimonK пишет:

Суть проги такова: на устройстве сигнализации нажимается кнопка, я отсылаю команду codes[1] - чтение буфера клавы и считываю ответ
УС понимает CP1251 кодировку. Пробовал без перекодировки - ни чего. Решил что необходима кодировка...

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

для начала попробуйте в консоли

 Консоль:
cat /dev/ttyS0 | xxd

Карусель разнесло по цепочке за час
Всех известий — конец
Да, весна началась!
(всё к лицу подлецу, как родному отцу, не рассказывай, батя, и так всё пройдёт)

10

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

printf("%X\t", buffer[i]);

потом нагуглите таблицу символов. ЕМНИП буква "я" имеет код 0xFF в 1251

Карусель разнесло по цепочке за час
Всех известий — конец
Да, весна началась!
(всё к лицу подлецу, как родному отцу, не рассказывай, батя, и так всё пройдёт)

11

Спасибо, drBatty smile
Попробуем...

12

Привет всем.

Что-то не получается  использовать коды(речь идет только о кириллице):
получаю код, а затем записываю его в определенный элемент массива char и затем отправляю его на устройство - кракозябра ac 
Попробовал вариант с утилитой iconv - работает (я из отформатированного файла копирую строку и вставляю в прогу). Но это для меня не панацея - и другие проги формирую сигналки, а затем отправляют мне...

Две входные строки: "$01T100TEXT\n" и "$01T100ТЕКСТ\n", а значение
res = 0 в обоих случаях-?

size_t res = iconv(cdout,&in,&numbin,&bout,&nbbout)

13

DimonK пишет:

Две входные строки: "$01T100TEXT\n" и "$01T100ТЕКСТ\n", а значение
res = 0 в обоих случаях-?

видимо в вашей строке 0 символов. так бывает, если в строке первый байт равен нулю (\0, а не "ноль").
iconv() возвращает число символов которые обработаны. Кроме того, возможно, первым у вас затесался НЕСИМВОЛ. Несимволы встречаются лишь в UTF-8, и им не соответствуют никакие символы. (это мало вероятно, ибо у меня получается -1 в res, и errno == EILSEQ. читайте СВОЮ документацию).

Карусель разнесло по цепочке за час
Всех известий — конец
Да, весна началась!
(всё к лицу подлецу, как родному отцу, не рассказывай, батя, и так всё пройдёт)

14

Может вы перейдёте в раздел программирование?

15

Привет всем
Спс, drBatty  smile

Vascom пишет:

Может вы перейдёте в раздел рограммирование?

- Хорошо. Вы можете ее туда отправить?

16

Вот программа для конвертирования из одной из четырёх русских кодировок
в другую. Она старая, автор не я и его давно нет в RU.LINUX, я её тогда же
несколько модернизировал. Там при её вызове method - это два символа,
каждый - один из четырёх: w, k, a, i.
Воспользуйтесь програмой indent.

Пётр.

#include <stdio.h>
//#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#define sblk 4096
//#define BUFSIZ sblk
unsigned char t256[260];
unsigned char win[68]={
0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7,
0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF, 0xA8, 0xB8,0,0};
unsigned char alt[68]={
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7,
0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1,0,0};
unsigned char koi8[68]={
0xE1, 0xE2, 0xF7, 0xE7, 0xE4, 0xE5, 0xF6, 0xFA,
0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0,
0xF2, 0xF3, 0xF4, 0xF5, 0xE6, 0xE8, 0xE3, 0xFE,
0xFB, 0xFD, 0xFF, 0xF9, 0xF8, 0xFC, 0xE0, 0xF1,
0xC1, 0xC2, 0xD7, 0xC7, 0xC4, 0xC5, 0xD6, 0xDA,
0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0,
0xD2, 0xD3, 0xD4, 0xD5, 0xC6, 0xC8, 0xC3, 0xDE,
0xDB, 0xDD, 0xDF, 0xD9, 0xD8, 0xDC, 0xC0, 0xD1, 0xB3, 0xA3,0,0};
unsigned char iso[68]={
0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7,
0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7,
0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xA1, 0xF1,0,0};
unsigned char altkoi[130]={
0xE1, 0xE2, 0xF7, 0xE7, 0xE4, 0xE5, 0xF6, 0xFA,
0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0,
0xF2, 0xF3, 0xF4, 0xF5, 0xE6, 0xE8, 0xE3, 0xFE,
0xFB, 0xFD, 0xFF, 0xF9, 0xF8, 0xFC, 0xE0, 0xF1,
0xC1, 0xC2, 0xD7, 0xC7, 0xC4, 0xC5, 0xD6, 0xDA,
0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0,
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
0x88, 0x89, 0xBA, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
0x98, 0x99, 0x9A, 0xBF, 0x9C, 0x9D, 0x9E, 0x9F,
0xA0, 0xA1, 0xA2, 0xB0, 0xA4, 0xA5, 0xA6, 0xA7,
0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
0xD2, 0xD3, 0xD4, 0xD5, 0xC6, 0xC8, 0xC3, 0xDE,
0xDB, 0xDD, 0xDF, 0xD9, 0xD8, 0xDC, 0xC0, 0xD1,
0xB3, 0xA3, 0xB2, 0xB1, 0xB4, 0xB5, 0xB6, 0xB7,
0xB8, 0xBC, 0x8A, 0xBB, 0x4E, 0xBD, 0xBE, 0x9B,0,0};
unsigned char koialt[130]={
0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7,
0xB8, 0xB9, 0xFA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
0xC8, 0xC9, 0xCA, 0xFF, 0xCC, 0xCD, 0xCE, 0xCF,
0xD0, 0xD1, 0xD2, 0xF1, 0xD4, 0xD5, 0xD6, 0xD7,
0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
0xD3, 0xF3, 0xF2, 0xF0, 0xF4, 0xF5, 0xF6, 0xF7,
0xF8, 0xD0, 0xBA, 0xFB, 0xF9, 0xFD, 0xFE, 0xCB,
0xEE, 0xA0, 0xA1, 0xE6, 0xA4, 0xA5, 0xE4, 0xA3,
0xE5, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE,
0xAF, 0xEF, 0xE0, 0xE1, 0xE2, 0xE3, 0xA6, 0xA2,
0xEC, 0xEB, 0xA7, 0xE8, 0xED, 0xE9, 0xE7, 0xEA,
0x9E, 0x80, 0x81, 0x96, 0x84, 0x85, 0x94, 0x83,
0x95, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E,
0x8F, 0x9F, 0x90, 0x91, 0x92, 0x93, 0x86, 0x82,
0x9C, 0x9B, 0x87, 0x98, 0x9D, 0x99, 0x97, 0x9A,0,0};
int main( int argc, char *argv[] ){
unsigned char buf[sblk],bufin[sblk],bufout[sblk],*from,*to,uc; //,*t;
size_t size=sblk, nit=1;    //, rblr=0,rblw=0;
void *vbuf=(void*)buf;    //, *vbufin=(void*)bufin, *vbufout=(void*)bufout;
FILE *in, *out;fpos_t pos; long il; //, ic=99;
char cfr,cto;int i,j,ifr=8,ito=2,inm, nbl, nrm=0, nccl, nccm, isz=sblk; //,c;
/*struct time tcur;*/
if ( argc != 4 ){
fprintf(stderr,"Usage: recsp <method> <file-in> <file-out>\n" );exit(-1);}
for(uc=0;uc<128;uc++)*(t256+uc)=uc;
cfr = (char)tolower (argv[1][0]);cto = (char)tolower (argv[1][1]);
switch(cfr){case 'a':ifr=0;from=alt;break;case 'k':ifr=8;from=koi8;break;
case 'w':ifr=64;from=win;break;case 'i':ifr=512;from=iso;break;
default: fprintf( stderr, "wrong coding 'from' method %c\n",cfr);exit(-1);}
switch(cto){case 'a':ito=0;to=alt;break;case 'k':ito=1;to=koi8;break;
case 'w':ito=2;to=win;break;case 'i':ito=3;to=iso;break;default: fprintf(stderr,
"wrong coding 'to' method %c\n",cto);exit(-1);}inm=ifr+ito;
if(inm==1||inm==8){switch(inm){case 1:from=altkoi;break;case 8:from=koialt;}
for(i=0;i<128;i++)t256[128+i]=from[i];}else for(i=0;i<66;i++)t256[from[i]]=to[i];
if ( ( in = fopen( argv[2], "rb" ) ) == NULL ){
fprintf(stderr, "cannot open file '%s' for reading\n", argv[2] );exit(-1);}
if ( ( out = fopen( argv[3], "wb+" ) ) == NULL ){
fprintf(stderr, "cannot open file '%s' for writing\n", argv[3] );exit(-1);}
fseek(in, 0L, SEEK_END); fgetpos( in, &pos);fseek(in, 0L, SEEK_SET);
il = pos.__pos;nccm=nccl=nbl=il/sblk; nrm=il-nbl*sblk; if(nrm != 0)nccm++;
setvbuf(in,(char*)bufin,_IOFBF,sblk);setvbuf(out,(char*)bufout,_IOFBF,sblk);
/*gettime(&tcur);
cprintf("\r\n%02d:%02d:%02d.%02d",tcur.ti_hour,tcur.ti_min,tcur.ti_sec,
tcur.ti_hund);*/
for(i=1; i<=nccm; i++){  if(i > nccl )size=isz=nrm;
/*for(j=0;j<sblk;j++)*(buf+j)=42;*/
/*if(i==nccl)rblr=fread(pbuf,size,nit, in);*/
         /*rblr=*/
       fread(vbuf,size,nit, in); for(j=0; j<isz; j++)*(buf+j)=*(t256+*(buf+j));
/*for(j=0; j<isz; j++)*(buf+j)=*(t256+(int)*(buf+j));*/
/*for(j=0; j<isz; j++){uc=*(bufin+j);*(bufout+j)=*(t256+uc);}*/
          /*  if(i==nccl)rblw=fwrite(pbuf,size,nit,out);*/
                 /*rblw=*/
           fwrite(vbuf,size,nit,out);
/*if(i == nccl)fflush(out);*/
/*if(i==nccl)cprintf("\n\r%3660s",buf);*/
/*cprintf("\n\r%6d%6d%6d%4d%4d%6d",i,isz,size,rblr,rblw,j);*/
}fflush(out);
/*gettime(&tcur);
cprintf("\r\n%02d:%02d:%02d.%02d",tcur.ti_hour,tcur.ti_min,tcur.ti_sec,
tcur.ti_hund);*/
/*cprintf("\n\r%8ld%6d%6d%6d",il,nbl,nrm,nccm);*/
/* cprintf("\n\r%c %ld %c",cto, il, cfr); */
return 0;}

/* Григорий Шпаков */
/* grigory@sirena2000.ru <mailto:grigory@sirena2000.ru> */
Пётр.

17

Привет всем
Спаибо за код, Peter smile

18 (21.02.2011 21:37:30 отредактировано Peter)

Насколько я помню, я добавил конвертирование символов псевдографики
CP866<->KOI8-R и эскпериментировал с буферизацией.

Пётр.

Пётр.