Привет программисты,
Я хочу чтение линию за линией Unicode (UTF-8) текстовый файл, созданный Блокнотом, я не хочу, отображают строку Unicode на экране, я хочу просто чтение и сравниваю строки!.
Этот код считал файл ANSI линию за линией и сравнивает строки
Прочитайте test_ansi.txt линию за линией
если строка = "b" печатает "ДА!"
еще распечатайте "НЕТ!"
#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;
}
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
#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 линию за линией, если строка = "ب" печатает "ДА!" еще распечатайте "НЕТ!"
#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, не уверенный)
Спасибо.
Я нашел решение моей проблемы, и я хотел бы поделиться решением любого, заинтересованного в чтении файла 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);
}
Приятное свойство UTF-8 заключается в том, что вы не должны быть не нужно декодировать, чтобы сравнить его. Заказ, возвращенный из StrCMP, будет то же самое, декодируете ли вы первым или нет. Так что просто прочитайте его как RAW BYTES и запустите STRCMP.
FGES () могут декодировать закодированные файлы utf-8, если вы используете Visual Studio 2005 и UP Отказ Измените свой код, как это:
infile = fopen(inname, "r, ccs=UTF-8");
Я знаю, что я плохой ... Но вы даже не принимаете При рассмотрении СБ! Большинство примеров здесь потерпят неудачу.
Редактировать:
Марки заказа байтов - это несколько байтов в 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 и Как мне обнаружить это?
В этой статье написана кодировка и рутина декодирования и Объясняется, как кодируется 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);
}
Просто для урегулирования аргумента 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
с домом в начале
лично я не думаю, что должен быть спецификацией (с момента своего формата байта), но это не точка