在C中读取一个Unicode文件,并通过套接字将内容作为ASCII传递

我正在试图弄清楚,但似乎没有任何工作。 我们有一个应用程序使用普通的“fopen fgets etc”读取数以千计的事务文件,我们使用普通的C函数“strstr,strchr等”parsing并返回规范化的char *。

但是,现在我们需要读取一些Unicode格式的文件(来自Windows),而且我遇到了很多麻烦。 从我的工作,我只收到一个FP(文件指针),而不知道FP指向一个正常的ASCII文件或Unicode,我需要发送回应用程序为char *。

我也不能运行命令行工具来手动转换整个文件,因为我们正在拖拽它的新条目。

我尝试使用WideCharToMultiByte,mbsrtowcs,但似乎在我读取文件使用fgets,并传递给他们,返回总是空的(0字节)。 任何人都有如何正确地做到这一点的例子? 这些function的在线文档/手册都错过了很好的例子。

谢谢!

我没有完整的答案,但问题的一部分是确定字符编码。 通常,在Windows中创建的unicode格式文件将以字节顺序标记(BOM)开始 – Unicode字符U + FEFF。 这可以用来确定什么是编码,如果找到。

如果你有一个使用UTF16编码的字符串,这将有任何数量的嵌入NULL字节,你不能使用正常的ASCII版本的字符串函数(strlen等),因为他们会看到NULL字节作为字符串的结尾标记。 您的标准库将使用您应该使用的启用Unicode的版本。

这是字符编码的问题之一 – 要么你必须假设它是在一些编码,你必须从数据中或从元数据中获取信息,或者你必须检测。

在Windows上,在文件开头使用字节顺序标记是很常见的,但是这违反了许多做法,并且破坏了很多东西 – 所以在UNIX环境中并不常见。

有一大堆专门为此而设计的库 – Unicode和字符编码。 最流行的是iconv和ICU 。

几点:

如果你能确定UNICODE文件有一个字节顺序标记(BOM),你可以看看这个。 但是,UNICODE文件不需要具有BOM,因此取决于它们来自哪里。

如果文件 UNICODE,你不能用fgets()读取它,你需要使用fgetws()或fread()。 UNICODE字符可能有零个字节(值为零的字节),这会混淆fgets()。

零字节可以是你的朋友。 如果使用fread()读取文件的块,并发现嵌入的零字节,则很可能是UNICODE。 然而反过来却不是这样 – 没有零字节并不能证明你有ASCII码。 UNICODE中的英文字母将会有零字节,但许多其他语言(例如中文)不会。

如果你知道文字是什么语言,你可以测试那种语言无效的字符 – 但是有点碰巧和错过。

在上面,我使用的是Windows下的“UNICODE” – 用英特尔字节顺序来引用UTF16。 但是,在现实世界中,您可以获得UTF8或UTF32,并且可能会获得非英特尔字节排序。 (理论上你可以得到UTF7,但这是非常罕见的)。

如果您可以控制输入文件,则可以坚持拥有物料清单(BOM),这使得它变得简单。

否则,如果你知道文件的语言,你可以尝试猜测编码,但这是不到100%可靠。 否则,您可能需要询问操作员(如果有的话)指定编码。