将 unicode 文件的包含复制到 c 中的 char 数组中
Copy contain of an unicode file in to the char array in c
我写了一个c代码如下,复制一个文件。它真正适用于 unicode
文件(例如 exe、rar),我使用 char
数据类型数组在其中复制文件 "block"。我知道,char data-type
只能存储 1
字节作为扩展 ASCII
标准。
in fread()
函数,使用 buffer[buflen]
变量作为 char
数组,因为复制了 exe
文件的一个块(100
字节)那,然后复制 buffer[buflen]
包含在另一个文件中。 unicode
个字符的块怎么可能存储在 char
中?为什么此代码真正适用于 unicode
个文件而没有任何问题?
copyFile
函数:
void copyFile(const char *src, const char *dst)
{
const int buflen = 100;
char buffer[buflen];
long fileSize, curFileSize, offset = 0;
FILE *r, *w;
r = fopen(src, "r+b");
w = fopen(dst, "w+b");
fseek(r, 0, SEEK_END);
fileSize = ftell(r);
fseek(r, 0, SEEK_SET);
while(fileSize - (curFileSize = ftell(r)) >= buflen)
{
fseek(r, offset * buflen, SEEK_SET);
fread(&buffer, sizeof(buffer), 1, r);
fwrite(&buffer, sizeof(buffer), 1, w);
offset++;
}
if ((fileSize - curFileSize) != 0)
{
fseek(r, (offset - 1) + (curFileSize), SEEK_SET);
fread(&buffer, fileSize - curFileSize, 1, r);
fwrite(&buffer, fileSize - curFileSize, 1, w);
}
fclose(w);
fclose(r);
}
entrypoint
节 :
int main()
{
copyFile("e:/1.exe", "e:/2.exe");
return 0;
}
在fread
和fwrite
函数中使用char
data-type
或struct
(包含char
)的原因是什么?
感谢大家的帮助。
任何文件,无论编码如何,都只是一个字节序列。 char
类型可以存储任何字节,因此您只是逐字节复制文件。 (char
在 C 和 C++ 中用作字符类型和能够容纳字节的数字类型。这可能会造成混淆,但两种用法都是有效的。)
fread
和 fwrite
是根据 char
指定的,因为它们读取和写入字节。
好吧,您正在阅读的文件可能会使用 utf-8 编码编码,这使得 utf 字符在 U+0000
---U+007f
与对应的 ASCII 相同(这允许正常读取,即使您没有符合 UNICODE 的 reader)。 iso-latin-?
集中的字符通常映射为两个字符序列,而像 €
这样的字符则映射为三个或更多字符序列。 只要您不修改正在读取的数据,存储的数据类型无关紧要——以二进制或文本开头,或使用的编码——,副本将是完全等于原来的(或者你将不得不查看你的代码,因为它正在改变副本,使其看起来与原来的不同)
通常情况下,你不会有任何问题,只要你不破坏这些序列中的任何一个(这意味着它们聚集到文件中并且你将它们分开写---到不同的地方---副本)这通常不会发生在文件副本中。确定 UTF-8 或 UTF-16 字符的开头相对容易,因为可以识别 UNICODE 编码中的所有字符,无论是在数据流中向前还是向后。
对于 UTF-8,字符由第一个字符和 n-1
个此类字符的尾部组成,第一个字符编码此字符的字节数(同样,很容易检测到)第一个字符将是 0b110xxxxx
(0b
表示从现在开始二进制表示中的八位字节)对于两个字节的字符,0b1110xxxx
对于三字节的字符,依此类推直到 0b1111110x
一个六字节字符)后面的其余字符编码为 0b10xxxxxx
。如果你继续前进,一旦你看到一个带有 MSB 集的字节,你就知道你在一个多字节序列的前面,你必须计算第一个 0
之前顶部的数量并且你有组成字符的字节。向后走,你首先遇到一个 0b10xxxxxx
字符,你必须向后走,直到你得到一个 0b11xxxxxx
字符,这将是序列中的第一个字符。然后你再次使用第一个过程。
在 UTF-16 中,过程几乎相同。 0x10000
下的字符被编码为一个 16 位数字,等于或大于 23= 的字符使用 16 位数字的代理对编码,它们具有以下模式:0b110110xxxxxxxxxx
代表该对的前 16 位, 0b110111xxxxxxxxxx
第二个。这一次,在得到两个 16 位数量的 xxxx...
部分的 x 之前,您必须将 0x10000
减去 UTF 字符数,但该过程类似于 utf-8 中使用的.
在UTF-32
编码中,所有的字符都存储为32bit的量,所以暂时没有多序列编码的计划。所有字符都作为 32 位数量传输。在撰写本文时,标准是 V8.0,包含 1,114,112 个代码点。
当使用另一种 UTF 编码时,例如 UTF-16,所有字符都被编码为 16 位数量,这可能会发生变化,例如,如果您在小端架构中读取它们,但您在大端架构中写入它们-endian 体系结构(您应该交换字符的每两个字节以在目标体系结构中保存它们的 UTF 值)但是同样,可以有一些技巧来解决这个问题(有一个 BOM 特殊签名允许检查字节顺序正在使用数据) 所以,只要你复制一个文件,一个字节一个字节,没有对字符进行重新排序,最终图像与你之前的图像完全相同,所以 UTF 不应该担心。
在可变长度编码(utf-5, utf-7、utf-8 和 utf-16)中,如果您打破映射到实际 UTF 代码的多个序列之一,就会出现问题,因为这会使字符非可被解码过程识别(它成为非法字符),然后您通常会在输出中得到一些特殊字符,表示检测到无效字符。在恒定长度编码 (utf-32) 中,只有当您在非 32 位边界的倍数处拆分文件时,您才会得到一个损坏的字符。
UTF 旨在成为一种有效的方式来存储和发送一组实际上未绑定的字符,为了实现这一点,它将最常见的字符映射(或尝试映射)为一个字节,增加了选择更具体或更稀有的字符时的长度。
关于 UNICODE 的主要信息来源在 UNICODE FORUM, where you will find specifications, guidelines and even character maps for the full UNICODE range. UTF-8, UTF-16 and UTF-32 encodings are described here. For utf-5 and utf-7,您必须点击上面的链接。
我写了一个c代码如下,复制一个文件。它真正适用于 unicode
文件(例如 exe、rar),我使用 char
数据类型数组在其中复制文件 "block"。我知道,char data-type
只能存储 1
字节作为扩展 ASCII
标准。
in fread()
函数,使用 buffer[buflen]
变量作为 char
数组,因为复制了 exe
文件的一个块(100
字节)那,然后复制 buffer[buflen]
包含在另一个文件中。 unicode
个字符的块怎么可能存储在 char
中?为什么此代码真正适用于 unicode
个文件而没有任何问题?
copyFile
函数:
void copyFile(const char *src, const char *dst)
{
const int buflen = 100;
char buffer[buflen];
long fileSize, curFileSize, offset = 0;
FILE *r, *w;
r = fopen(src, "r+b");
w = fopen(dst, "w+b");
fseek(r, 0, SEEK_END);
fileSize = ftell(r);
fseek(r, 0, SEEK_SET);
while(fileSize - (curFileSize = ftell(r)) >= buflen)
{
fseek(r, offset * buflen, SEEK_SET);
fread(&buffer, sizeof(buffer), 1, r);
fwrite(&buffer, sizeof(buffer), 1, w);
offset++;
}
if ((fileSize - curFileSize) != 0)
{
fseek(r, (offset - 1) + (curFileSize), SEEK_SET);
fread(&buffer, fileSize - curFileSize, 1, r);
fwrite(&buffer, fileSize - curFileSize, 1, w);
}
fclose(w);
fclose(r);
}
entrypoint
节 :
int main()
{
copyFile("e:/1.exe", "e:/2.exe");
return 0;
}
在fread
和fwrite
函数中使用char
data-type
或struct
(包含char
)的原因是什么?
感谢大家的帮助。
任何文件,无论编码如何,都只是一个字节序列。 char
类型可以存储任何字节,因此您只是逐字节复制文件。 (char
在 C 和 C++ 中用作字符类型和能够容纳字节的数字类型。这可能会造成混淆,但两种用法都是有效的。)
fread
和 fwrite
是根据 char
指定的,因为它们读取和写入字节。
好吧,您正在阅读的文件可能会使用 utf-8 编码编码,这使得 utf 字符在 U+0000
---U+007f
与对应的 ASCII 相同(这允许正常读取,即使您没有符合 UNICODE 的 reader)。 iso-latin-?
集中的字符通常映射为两个字符序列,而像 €
这样的字符则映射为三个或更多字符序列。 只要您不修改正在读取的数据,存储的数据类型无关紧要——以二进制或文本开头,或使用的编码——,副本将是完全等于原来的(或者你将不得不查看你的代码,因为它正在改变副本,使其看起来与原来的不同)
通常情况下,你不会有任何问题,只要你不破坏这些序列中的任何一个(这意味着它们聚集到文件中并且你将它们分开写---到不同的地方---副本)这通常不会发生在文件副本中。确定 UTF-8 或 UTF-16 字符的开头相对容易,因为可以识别 UNICODE 编码中的所有字符,无论是在数据流中向前还是向后。
对于 UTF-8,字符由第一个字符和 n-1
个此类字符的尾部组成,第一个字符编码此字符的字节数(同样,很容易检测到)第一个字符将是 0b110xxxxx
(0b
表示从现在开始二进制表示中的八位字节)对于两个字节的字符,0b1110xxxx
对于三字节的字符,依此类推直到 0b1111110x
一个六字节字符)后面的其余字符编码为 0b10xxxxxx
。如果你继续前进,一旦你看到一个带有 MSB 集的字节,你就知道你在一个多字节序列的前面,你必须计算第一个 0
之前顶部的数量并且你有组成字符的字节。向后走,你首先遇到一个 0b10xxxxxx
字符,你必须向后走,直到你得到一个 0b11xxxxxx
字符,这将是序列中的第一个字符。然后你再次使用第一个过程。
在 UTF-16 中,过程几乎相同。 0x10000
下的字符被编码为一个 16 位数字,等于或大于 23= 的字符使用 16 位数字的代理对编码,它们具有以下模式:0b110110xxxxxxxxxx
代表该对的前 16 位, 0b110111xxxxxxxxxx
第二个。这一次,在得到两个 16 位数量的 xxxx...
部分的 x 之前,您必须将 0x10000
减去 UTF 字符数,但该过程类似于 utf-8 中使用的.
在UTF-32
编码中,所有的字符都存储为32bit的量,所以暂时没有多序列编码的计划。所有字符都作为 32 位数量传输。在撰写本文时,标准是 V8.0,包含 1,114,112 个代码点。
当使用另一种 UTF 编码时,例如 UTF-16,所有字符都被编码为 16 位数量,这可能会发生变化,例如,如果您在小端架构中读取它们,但您在大端架构中写入它们-endian 体系结构(您应该交换字符的每两个字节以在目标体系结构中保存它们的 UTF 值)但是同样,可以有一些技巧来解决这个问题(有一个 BOM 特殊签名允许检查字节顺序正在使用数据) 所以,只要你复制一个文件,一个字节一个字节,没有对字符进行重新排序,最终图像与你之前的图像完全相同,所以 UTF 不应该担心。
在可变长度编码(utf-5, utf-7、utf-8 和 utf-16)中,如果您打破映射到实际 UTF 代码的多个序列之一,就会出现问题,因为这会使字符非可被解码过程识别(它成为非法字符),然后您通常会在输出中得到一些特殊字符,表示检测到无效字符。在恒定长度编码 (utf-32) 中,只有当您在非 32 位边界的倍数处拆分文件时,您才会得到一个损坏的字符。
UTF 旨在成为一种有效的方式来存储和发送一组实际上未绑定的字符,为了实现这一点,它将最常见的字符映射(或尝试映射)为一个字节,增加了选择更具体或更稀有的字符时的长度。
关于 UNICODE 的主要信息来源在 UNICODE FORUM, where you will find specifications, guidelines and even character maps for the full UNICODE range. UTF-8, UTF-16 and UTF-32 encodings are described here. For utf-5 and utf-7,您必须点击上面的链接。