我正在尝试从文本文件中读取UTF8文本,然后将其中的一些文本打印到另一个文件中。我正在使用Linux和gcc编译器。这是我正在使用的代码:
#include <stdio.h>
#include <stdlib.h>
int main(){
FILE *fin;
FILE *fout;
int character;
fin=fopen("in.txt", "r");
fout=fopen("out.txt","w");
while((character=fgetc(fin))!=EOF){
putchar(character); // It displays the right character (UTF8) in the terminal
fprintf(fout,"%c ",character); // It displays weird characters in the file
}
fclose(fin);
fclose(fout);
printf("\nFile has been created...\n");
return 0;
}
目前适用于英文字符。
答案 0 :(得分:14)
而不是
fprintf(fout,"%c ",character);
使用
fprintf(fout,"%c",character);
第二个fprintf()
在%c
之后不包含空格,这是导致 out.txt 显示奇怪字符的原因。原因是fgetc()
正在检索单个字节(与ASCII字符相同),不是 UTF-8字符。由于UTF-8也兼容ASCII,它会将英文字符写入文件。
putchar(character)
按顺序输出字节,每个字节之间没有额外的空格,因此原始的UTF-8序列保持不变。要了解我在说什么,请尝试
while((character=fgetc(fin))!=EOF){
putchar(character);
printf(" "); // This mimics what you are doing when you write to out.txt
fprintf(fout,"%c ",character);
}
如果要将UTF-8字符与它们之间的空格写入out.txt,则需要处理UTF-8字符的可变长度编码。
#include <stdio.h>
#include <stdlib.h>
/* The first byte of a UTF-8 character
* indicates how many bytes are in
* the character, so only check that
*/
int numberOfBytesInChar(unsigned char val) {
if (val < 128) {
return 1;
} else if (val < 224) {
return 2;
} else if (val < 240) {
return 3;
} else {
return 4;
}
}
int main(){
FILE *fin;
FILE *fout;
int character;
fin = fopen("in.txt", "r");
fout = fopen("out.txt","w");
while( (character = fgetc(fin)) != EOF) {
for (int i = 0; i < numberOfBytesInChar((unsigned char)character) - 1; i++) {
putchar(character);
fprintf(fout, "%c", character);
character = fgetc(fin);
}
putchar(character);
printf(" ");
fprintf(fout, "%c ", character);
}
fclose(fin);
fclose(fout);
printf("\nFile has been created...\n");
return 0;
}
答案 1 :(得分:1)
此代码对我有用:
/* fgetwc example */
#include <stdio.h>
#include <wchar.h>
#include <stdlib.h>
#include <locale.h>
int main ()
{
setlocale(LC_ALL, "en_US.UTF-8");
FILE * fin;
FILE * fout;
wint_t wc;
fin=fopen ("in.txt","r");
fout=fopen("out.txt","w");
while((wc=fgetwc(fin))!=WEOF){
// work with: "wc"
}
fclose(fin);
fclose(fout);
printf("File has been created...\n");
return 0;
}
答案 2 :(得分:0)
如果您不想使用广泛选项,请尝试以下操作:
读写字节,而不是字符。 也称为,使用二进制,而不是文本。
fgetc有效地从文件中获取一个字节,但如果该字节大于127,请尝试将其视为int而不是char。 另一方面,fputc默默地忽略了放置一个字符&gt;如果使用int而不是char作为输入,它将起作用。
另外,在开放模式下,尝试使用二进制,所以试试rb&amp; wb而不是r&amp;瓦特
答案 3 :(得分:0)
C风格的解决方案非常有洞察力,但如果你考虑使用C ++,任务就会变得更高,并且它不需要你对utf-8编码有太多的了解。请考虑以下事项:
#include<iostream>
#include<fstream>
int main(){
wifstream input { "in.txt" }
wofstream output { "out.txt" }
// Look out - this part is not portable to windows
locale utf8 {"en_us.UTF-8"};
input.imbue(utf8);
output.imbue(utf8);
wcout.imbue(utf8);
wchar_t c;
while(input >> noskipws >> c) {
wcout << c;
output << c;
}
return 0;
}