Как считать unicode (utf-8) / двоичный файл линию за линией

Привет программисты,

Я хочу чтение линию за линией Unicode (UTF-8) текстовый файл, созданный Блокнотом, я не хочу, отображают строку Unicode на экране, я хочу просто чтение и сравниваю строки!.

Этот код считал файл ANSI линию за линией и сравнивает строки

Что я хочу

Прочитайте test_ansi.txt линию за линией

если строка = "b" печатает "ДА!"

еще распечатайте "НЕТ!"

read_ansi_line_by_line.c

#include <stdio.h>

int main()
{
    char *inname = "test_ansi.txt";
    FILE *infile;
    char line_buffer[BUFSIZ]; /* BUFSIZ is defined if you include stdio.h */
    char line_number;

    infile = fopen(inname, "r");
    if (!infile) {
        printf("\nfile '%s' not found\n", inname);
        return 0;
    }
    printf("\n%s\n\n", inname);

    line_number = 0;
    while (fgets(line_buffer, sizeof(line_buffer), infile)) {
        ++line_number;
        /* note that the newline is in the buffer */
        if (strcmp("b\n", line_buffer) == 0 ){
            printf("%d: YES!\n", line_number);
        }else{
            printf("%d: NO!\n", line_number,line_buffer);
        }
    }
    printf("\n\nTotal: %d\n", line_number);
    return 0;
}

test_ansi.txt

a
b
c

Компиляция

gcc -o read_ansi_line_by_line read_ansi_line_by_line.c

Вывод

test_ansi.txt

1: NO!
2: YES!
3: NO!


Total: 3

Теперь я должен считать Unicode (UTF-8) файл, созданный Блокнотом, после того, как больше чем 6 месяцев, которые я не делаю, нашли, что любой хороший код/библиотека в C может считать файл, кодированный в UTF-8!, я не знаю точно, почему, но я думаю, что стандарт C не поддерживает Unicode!

Чтение двоичного файла Unicode его OK!, но probleme является двоичным файлом большинство быть уже созданным в режиме двоичного счета!, это означает, хотим ли мы, читает Unicode (UTF-8) файл, созданный Блокнотом, мы должны перевести его от файла UTF-8 до ДВОИЧНОГО ФАЙЛА!

Эта строка Unicode записи кода к двоичному файлу, ОБРАТИТЕ ВНИМАНИЕ, что файл C кодируется в UTF-8 и компилируется GCC

Что я хочу

Запишите символ Unicode "ب" в test_bin.dat

create_bin.c

#define UNICODE
#ifdef UNICODE
#define _UNICODE
#else
#define _MBCS
#endif

#include <stdio.h>
#include <wchar.h>

int main()
{
     /*Data to be stored in file*/
     wchar_t line_buffer[BUFSIZ]=L"ب";
     /*Opening file for writing in binary mode*/
     FILE *infile=fopen("test_bin.dat","wb");
     /*Writing data to file*/
     fwrite(line_buffer, 1, 13, infile);
     /*Closing File*/
     fclose(infile);

    return 0;
}

Компиляция

gcc -o create_bin create_bin.c

Вывод

create test_bin.dat

Теперь я хочу, читает двоичный файл линию за линией и выдерживают сравнение!

Что я хочу

Считайте test_bin.dat линию за линией, если строка = "ب" печатает "ДА!" еще распечатайте "НЕТ!"

read_bin_line_by_line.c

#define UNICODE
#ifdef UNICODE
#define _UNICODE
#else
#define _MBCS
#endif

#include <stdio.h>
#include <wchar.h>

int main()
{
    wchar_t *inname = L"test_bin.dat";
    FILE *infile;
    wchar_t line_buffer[BUFSIZ]; /* BUFSIZ is defined if you include stdio.h */

    infile = _wfopen(inname,L"rb");
    if (!infile) {
        wprintf(L"\nfile '%s' not found\n", inname);
        return 0;
    }
    wprintf(L"\n%s\n\n", inname);

    /*Reading data from file into temporary buffer*/
    while (fread(line_buffer,1,13,infile)) {
        /* note that the newline is in the buffer */
        if ( wcscmp ( L"ب" , line_buffer ) == 0 ){
             wprintf(L"YES!\n");
        }else{
             wprintf(L"NO!\n", line_buffer);
        }
    }
    /*Closing File*/
    fclose(infile);
    return 0;
}

Вывод

test_bin.dat

YES!

ПРОБЛЕМА

Этот метод ОЧЕНЬ ДЛИНЕН! и НЕ МОЩНЫЙ (я m новичок в разработке программного обеспечения)

Кто-либо знает, как считать файл Unicode? (я знаю не легкий!) Нравятся, что кто-либо знает, как преобразовать файл Unicode в Двоичный файл? (простому методу) Нравится, что кто-либо знает, как считать файл Unicode в режиме двоичного счета? (я m, не уверенный)

Спасибо.

12
задан sepehr 21 January 2010 в 23:03
поделиться

6 ответов

Я нашел решение моей проблемы, и я хотел бы поделиться решением любого, заинтересованного в чтении файла UTF-8 в C99 Отказ

void ReadUTF8(FILE* fp)
{
    unsigned char iobuf[255] = {0};
    while( fgets((char*)iobuf, sizeof(iobuf), fp) )
    {
            size_t len = strlen((char *)iobuf);
            if(len > 1 &&  iobuf[len-1] == '\n')
                iobuf[len-1] = 0;
            len = strlen((char *)iobuf);
            printf("(%d) \"%s\"  ", len, iobuf);
            if( iobuf[0] == '\n' )
                printf("Yes\n");
            else
                printf("No\n");
    }
}

void ReadUTF16BE(FILE* fp)
{
}

void ReadUTF16LE(FILE* fp)
{
}

int main()
{
    FILE* fp = fopen("test_utf8.txt", "r");
    if( fp != NULL)
    {
        // see http://en.wikipedia.org/wiki/Byte-order_mark for explaination of the BOM
        // encoding
        unsigned char b[3] = {0};
        fread(b,1,2, fp);
        if( b[0] == 0xEF && b[1] == 0xBB)
        {
            fread(b,1,1,fp); // 0xBF
            ReadUTF8(fp);
        }
        else if( b[0] == 0xFE && b[1] == 0xFF)
        {
            ReadUTF16BE(fp);
        }
        else if( b[0] == 0 && b[1] == 0)
        {
            fread(b,1,2,fp); 
            if( b[0] == 0xFE && b[1] == 0xFF)
                ReadUTF16LE(fp);
        }
        else
        {
            // we don't know what kind of file it is, so assume its standard
            // ascii with no BOM encoding
            rewind(fp);
            ReadUTF8(fp);
        }
    }        

    fclose(fp);
}
5
ответ дан 2 December 2019 в 19:54
поделиться

Приятное свойство UTF-8 заключается в том, что вы не должны быть не нужно декодировать, чтобы сравнить его. Заказ, возвращенный из StrCMP, будет то же самое, декодируете ли вы первым или нет. Так что просто прочитайте его как RAW BYTES и запустите STRCMP.

6
ответ дан 2 December 2019 в 19:54
поделиться

FGES () могут декодировать закодированные файлы utf-8, если вы используете Visual Studio 2005 и UP Отказ Измените свой код, как это:

infile = fopen(inname, "r, ccs=UTF-8");
2
ответ дан 2 December 2019 в 19:54
поделиться

Я знаю, что я плохой ... Но вы даже не принимаете При рассмотрении СБ! Большинство примеров здесь потерпят неудачу.

Редактировать:

Марки заказа байтов - это несколько байтов в Beadnig от файла, который можно использовать для идентификации кодирования файла. Некоторые редакторы добавляют их, и много раз они просто разбивают вещи в Faboulous Ways (я помню, как бороться с проблемами заголовков PHP в течение нескольких минут из-за этого вопроса).

Некоторые RTFM: http://en.wikipedia.org/wiki/byte_order_mark http://blogs.msdn.com/oldnewhing/archive/2004/03/24/95235.aspx Что такое XML BOM и Как мне обнаружить это?

2
ответ дан 2 December 2019 в 19:54
поделиться

В этой статье написана кодировка и рутина декодирования и Объясняется, как кодируется Unicode:

http://www.codeguru.com/cpp/misc/misc/multi-lingualsupport/article.php/c10451/

Это может быть легко настроить до C. Просто кодируйте свой ANSI или декодируйте строку UTF-8 и сделайте байт Сравните

Редактировать: после того, как OP сказал, что слишком сложно переписать функцию от C ++ Здесь шаблон:

Что нужно:
+ Бесплатная выделенная память (или подожди, пока процесс не заканчивается или не проигнорирует)
+ Добавить 4 байтовые функции
+ Скажите, что короткая короткая и int не гарантированно будет 2 и 4 байта долго (я знаю, но C действительно глуп!) И наконец
+ Найти некоторые другие ошибки

#include <stdlib.h>
#include <string.h>

#define         MASKBITS                0x3F
#define         MASKBYTE                0x80
#define         MASK2BYTES              0xC0
#define         MASK3BYTES              0xE0
#define         MASK4BYTES              0xF0
#define         MASK5BYTES              0xF8
#define         MASK6BYTES              0xFC

char* UTF8Encode2BytesUnicode(unsigned short* input)
{
   int size = 0,
       cindex = 0;
   while (input[size] != 0)
     size++;
   // Reserve enough place; The amount of 
   char* result = (char*) malloc(size);
   for (int i=0; i<size; i++)
   {
      // 0xxxxxxx
      if(input[i] < 0x80)
      {
         result[cindex++] = ((char) input[i]);
      }
      // 110xxxxx 10xxxxxx
      else if(input[i] < 0x800)
      {
         result[cindex++] = ((char)(MASK2BYTES | input[i] >> 6));
         result[cindex++] = ((char)(MASKBYTE | input[i] & MASKBITS));
      }
      // 1110xxxx 10xxxxxx 10xxxxxx
      else if(input[i] < 0x10000)
      {
         result[cindex++] = ((char)(MASK3BYTES | input[i] >> 12));
         result[cindex++] = ((char)(MASKBYTE | input[i] >> 6 & MASKBITS));
         result[cindex++] = ((char)(MASKBYTE | input[i] & MASKBITS));
      }
   }
}

wchar_t* UTF8Decode2BytesUnicode(char* input)
{
  int size = strlen(input);
  wchar_t* result = (wchar_t*) malloc(size*sizeof(wchar_t));
  int rindex = 0,
      windex = 0;
  while (rindex < size)
  {
      wchar_t ch;

      // 1110xxxx 10xxxxxx 10xxxxxx
      if((input[rindex] & MASK3BYTES) == MASK3BYTES)
      {
         ch = ((input[rindex] & 0x0F) << 12) | (
               (input[rindex+1] & MASKBITS) << 6)
              | (input[rindex+2] & MASKBITS);
         rindex += 3;
      }
      // 110xxxxx 10xxxxxx
      else if((input[rindex] & MASK2BYTES) == MASK2BYTES)
      {
         ch = ((input[rindex] & 0x1F) << 6) | (input[rindex+1] & MASKBITS);
         rindex += 2;
      }
      // 0xxxxxxx
      else if(input[rindex] < MASKBYTE)
      {
         ch = input[rindex];
         rindex += 1;
      }

      result[windex] = ch;
   }
}

char* getUnicodeToUTF8(wchar_t* myString) {
  int size = sizeof(wchar_t);
  if (size == 1)
    return (char*) myString;
  else if (size == 2)
    return UTF8Encode2BytesUnicode((unsigned short*) myString);
  else
    return UTF8Encode4BytesUnicode((unsigned int*) myString);
}
2
ответ дан 2 December 2019 в 19:54
поделиться

Просто для урегулирования аргумента BOM. Вот файл из Блокнота

 [paul@paul-es5 tests]$ od -t x1 /mnt/hgfs/cdrive/test.txt
 0000000 ef bb bf 61 0d 0a 62 0d 0a 63
 0000012

с домом в начале

лично я не думаю, что должен быть спецификацией (с момента своего формата байта), но это не точка

0
ответ дан 2 December 2019 в 19:54
поделиться
Другие вопросы по тегам:

Похожие вопросы: