首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何用C语言读写UTF8文本文件?

如何用C语言读写UTF8文本文件?
EN

Stack Overflow用户
提问于 2014-02-12 19:37:58
回答 4查看 39.1K关注 0票数 6

我正在尝试从文本文件中读取UTF8文本,然后将其中一些文本打印到另一个文件中。我正在使用Linux和gcc编译器。这是我正在使用的代码:

代码语言:javascript
运行
复制
#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;
}

它现在适用于英文字符。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2014-02-14 09:25:41

这段代码适用于我:

代码语言:javascript
运行
复制
/* 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;
}
票数 5
EN

Stack Overflow用户

发布于 2014-02-13 04:23:02

而不是

代码语言:javascript
运行
复制
fprintf(fout,"%c ",character);

使用

代码语言:javascript
运行
复制
fprintf(fout,"%c",character);

第二个fprintf()不包含%c后面的空格,这就是导致out.txt显示奇怪字符的原因。原因是fgetc()正在检索单个字节(与ASCII字符相同),而不是是UTF-8字符。由于UTF-8也是与ASCII兼容的,所以它会将英文字符写入文件中。

putchar(character)按顺序输出字节,每个字节之间没有额外的空间,因此原始的UTF-8序列保持原样。想知道我在说什么,试试

代码语言:javascript
运行
复制
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字符的可变长度编码。

代码语言:javascript
运行
复制
#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;
}
票数 18
EN

Stack Overflow用户

发布于 2015-12-05 21:26:54

如果您不希望使用广泛的选项,请尝试以下内容:

读取和写入字节,而不是字符。也称为二进制,而不是文本。

fgetc有效地从文件中获取一个字节,但是如果字节大于127,则尝试将其视为int而不是char。另一方面,fputc默默地忽略了放置一个字符> 127。如果您使用int而不是char作为输入,它将工作。

此外,在开放模式下,尝试使用二进制,所以尝试rb和wb而不是r&w。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21737906

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档