LINUX.ORG.RU

convert to UNICODE


0

0

Всем привет. Мне впервые пришлось подправить исходники программы написаной под Linux. И сразу проблема, т.к. я всё писал только под Windows я не имею представления о Linux API.

Подскажите функцию, хидер и либы, необходимые для перекодировки текста в ЮНИКОД и обратно... А лучше скажите в дробавок где в будующем это искать... Аля MSDN есть какой-нить?

набери в шелл: man iconv

agat
()

Нет такого говорит. Мож у меня что не установлено? Что должно быть?

Spider84
() автор топика

Попробуй info libc Charactes Set Handling...

subj

DonkeyHot ★★★★★
()

Странно, что в твоем линуксе нет мана на iconv - все-таки
это часть glibc. Ну да ладно, вот тебе чтиво:

http://www.gnu.org/manual/glibc-2.2.5/libc.html

а ниже как пример wrapper-функция из моего дипломного 
проекта:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <iconv.h>

char *
convCharset (const char *from, 
             const char *to, 
             char *str, 
             int *size)
{
    char *out;

    if (*size <= 0) {
        out = strdup ("");
    } else {
        char *buf, *holder;
        int insize, outsize, bufsize, r;
        iconv_t cd;

        cd = iconv_open (to, from);
        if (cd == (iconv_t) -1)
            return NULL;

        insize = *size;
        /* 
         * estimated size of output string: 
         * this should be enough for all encodings,
         * worst case: 8 bit x 4 = 32 bit for each character
         */ 
        outsize = bufsize = insize * 4;

        buf = (char *) malloc (bufsize);
        if (!buf) {
            fprintf (stderr, "Error: %s\n", 
                     strerror (errno));
            exit (1);
        }
        holder = buf;
        
        /* perfome convert */
        r = iconv (cd, &str, &insize, &buf, &outsize);
        if (r < 0 || insize != 0) {
            free (holder);
            iconv_close (cd);
            return NULL;
        }       
                
  
        /* calculate size of output string */   
        *size = bufsize - outsize;
        buf -= *size;


        /* copy converted characters from buffer */ 
        out = (char *) malloc (*size);
        if (!out) {
            fprintf (stderr, "Error: %s\n", 
                     strerror (errno));
            exit (1);
        }
        memcpy (out, buf, *size);

         
        free (holder);
        iconv_close (cd);
    }    
   
    return out;
}   

Пример:

...
char *str = "Пример";
int size;
size = strlen (str);
out = convCharset ("KOI8-R", "UTF-8", str, &size);
/* now size is actually number of bytes in out */
...

Успехов!

agat
()

/* * estimated size of output string: * this should be enough for all encodings, * worst case: 8 bit x 4 = 32 bit for each character */ outsize = bufsize = insize * 4;

Почему на 4? Неужели есть кодировки с символом в 4 байта?

Spider84
() автор топика

Есть и 4 байтовые кодировки, но это конечно не часто используется (http://www.unicode.org/unicode/reports/tr19). Я писал DVB stack для спутникового ресивера - хотелось, чтоб в любой обстановке все работало :-)

agat
()

после memcpy (out, buf, *size);

вставить out[*size]='\0' предварительно увеличив size на 1. Т.к. частенько получал результирующую строку вида СТРОКА+ЧУШЬ, где ЧУШЬ, всё, что в памяти за стракой :) NullTerminated однако...

Spider84
() автор топика

Я намеренно не использовал NULL terminated строки, т.к. было
проще и надежней иметь такую структуру:

struct __UTFString
{
    unsigned int len;
    unsigned char *str;
};

Т.к. считывал я из unsigned char буффера и составлять из
отдельных байтов каждый символ, мне показалось муторно, тем
более что редкий телеканал корректно передает кодировку. 
А так при любой кодировке для меня все строки - просто 
секвенция байтов определенной длины.

agat
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.