gpt4 book ai didi

c - 如果您知道字符编码,您将如何从 C 语言的文本文件中读取,然后将其显示在控制台上?

转载 作者:太空宇宙 更新时间:2023-11-04 00:03:19 24 4
gpt4 key购买 nike

在 Java 中考虑这个例子:

public final class Meh
{
private static final String HELLO = "Hello world";

private static final Charset UTF32 = Charset.forName("UTF-32");

public static void main(final String... args)
throws IOException
{
final Path tmpfile = Files.createTempFile("test", "txt");

try (
final Writer writer = Files.newBufferedWriter(tmpfile, UTF32);
) {
writer.write(HELLO);
}

final String readBackFromFile;

try (
final Reader reader = Files.newBufferedReader(tmpfile, UTF32);
) {
readBackFromFile = CharStreams.toString(reader);
}

Files.delete(tmpfile);

System.out.println(HELLO.equals(readBackFromFile));
}
}

这个程序打印true。现在,一些注意事项:

    Java 中的
  • Charset 是一个包装字符编码的类,两种方式;你可以获得一个 CharsetDecoder 来将字节流解码为字符流,或者一个 CharsetEncoder 来将字符流编码为字节流;
  • 这就是为什么 Java 有 charbyte 的原因;
  • 然而,由于历史原因,char 只是一个 16 位无符号数:这是因为当 Java 诞生时,Unicode 没有定义现在称为 BMP(基本多语言平面;也就是说,在 U+0000-U+FFFF 范围内定义的任何代码点,包括在内)。

完成所有这些后,上面的代码将执行以下操作:

  • 给定一些“文本”,此处表示为 String,它首先将此文本转换为字节序列,然后再将其写入文件;
  • 然后它读回那个文件:它只是一个字节序列,然后它应用反向转换来找回存储在其中的“原始文本”;
  • 请注意 CharStreams.toString() 不在标准 JDK 中;这是 Guava 的一个类。

现在,关于 C... 我的问题如下:

是的,我知道 UTF-32 依赖字节顺序;对于 Java,默认情况下是 BE。

但基本上:我将如何在 C 中编写上述程序?假设我想用 C 编写写入端或读取端的程序,我该怎么做?

最佳答案

在 C 中,您通常会使用像 libiconvlibunistringICU 这样的库。

如果只想处理 UTF-32,可以直接写入和读取包含 Unicode 代码点的 32 位整数数组,无论是小端还是大端。与 UTF-8 或 UTF-16 不同,UTF-32 字符串不需要任何特殊的编码和解码。您可以使用任何 32 位整数类型。我更喜欢 C99 的 uint32_t 而不是 C11 的 char32_t。例如:

#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main() {
// Could also contain non-ASCII code points.
static const uint32_t hello[] = {
'H', 'e', 'l', 'l', 'o', ' ',
'w', 'o', 'r', 'l', 'd'
};
static size_t num_chars = sizeof(hello) / sizeof(uint32_t);

const char *path = "test.txt";

FILE *outstream = fopen(path, "wb");

// Write big endian 32-bit integers
for (size_t i = 0; i < num_chars; i++) {
uint32_t code_point = hello[i];

for (int j = 0; j < 4; j++) {
int c = (code_point >> ((3 - j) * 8)) & 0xFF;
fputc(c, outstream);
}
}

fclose(outstream);

FILE *instream = fopen(path, "rb");

// Get file size.
fseek(instream, 0, SEEK_END);
long file_size = ftell(instream);
rewind(instream);

if (file_size % 4) {
fprintf(stderr, "File contains partial UTF-32");
exit(1);
}
if (file_size > SIZE_MAX) {
fprintf(stderr, "File too large");
exit(1);
}

size_t num_chars_in = file_size / sizeof(uint32_t);
uint32_t *read_back = malloc(file_size);

// Read big endian 32-bit integers
for (size_t i = 0; i < num_chars_in; i++) {
uint32_t code_point = 0;

for (int j = 0; j < 4; j++) {
int c = fgetc(instream);
code_point |= c << ((3 - j) * 8);
}

read_back[i] = code_point;
}

fclose(instream);

bool equal = num_chars == num_chars_in
&& memcmp(hello, read_back, file_size) == 0;
printf("%s\n", equal ? "true" : "false");

free(read_back);

return 0;
}

(为简洁起见省略了大多数错误检查。)

编译并运行这个程序:

$ gcc -std=c99 -Wall so.c -o so
$ ./so
true
$ hexdump -C test.txt
00000000 00 00 00 48 00 00 00 65 00 00 00 6c 00 00 00 6c |...H...e...l...l|
00000010 00 00 00 6f 00 00 00 20 00 00 00 77 00 00 00 6f |...o... ...w...o|
00000020 00 00 00 72 00 00 00 6c 00 00 00 64 |...r...l...d|
0000002c

关于c - 如果您知道字符编码,您将如何从 C 语言的文本文件中读取,然后将其显示在控制台上?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33961345/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com