2014-11-24 48 views
0

也许我有错误的想法 - 但我的理解是,宽类型(即wchar_t等)是UTF-16 Unicode类型。如果这是正确的,那么我无法理解对类似问题的响应泛滥,所有这些都涉及某种形式的wchar_t,或者使用UTF-8进行其他“宽泛”转换。字符编码和类型 - C/C++

我正在做一个带有MSVC的CLI/C++项目,它使用一个Luac实现来编译Lua代码到字节码。现在在这方面一切都很好,但麻烦在于对UTF-8文件没有特别的处理 - 除了“丢弃”BOM之外。因此,所有的数据都被视为ANSI。显然,当涉及到特殊字符时,正确显示它们会成为问题。因此,我需要一种方法来转换两者之间 - 最好在源(fopen);但是由于我已经改变了输出,所以我也可以在那里做。不幸的是,我发现的唯一有前途的解决方案 - 使用FILE* fh=fopen(fn,"r,css=UTF-8);只是最终导致无效文件模式的例外。考虑到它是一个Visual C++项目,这令人费解。

除非当然,我需要改变我的包括订单/添加一个额外的包括?

/lauxlib.c 
#include <ctype.h> 
#include <errno.h> 
#include <stdarg.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include "lua.h" 
#include "lauxlib.h"  


/lauxlib.h 
#include <stddef.h> 
#include <stdio.h> 
#include "lua.h" 

编辑: 考虑看看在十六进制编辑器文件后,我开始明白了。 UTF-8不仅仅是1字节,而且它的可以是就是1字节。最初的问题仍然存在,但至少我更了解它。

EDIT2 /更新: 首先,我不知道,如果这部分应该是一个答案,或者我是否应该关闭的问题 - 所以请随时来教育我这一点。

该应用程序最初被编写为控制台应用程序 - 所以当它需要输出时,它只是使用putchar或printf。但是,这不会对WinForms应用程序有所帮​​助。所以我基本上只是通过制作托管友好的等价物来重新路由它。

Luac本质上是Lua脚本的解析器/编译器。它可以根据解析结果输出信息。列出诸如函数,操作码,常量和局部变量之类的东西。当它打印出每个函数的常量时,它会打印出所述常量的实际值。而这其中编码问题出现在

如果常量的值是一个字符串类型,写入处理打印字符串的函数,执行以下操作:

  1. 蒙上了它的参数 - 一个指向工会。键入const char *
  2. 通过const char *通过索引循环,将char的值赋给int
  3. 通过switch/case(tab,newline等)检查文本中的任何转义字符,并逃脱他们
  4. 如果通过,默认案件检查,如果它是一个可打印字符,使用isprint
  5. 如果是,它采用putchar
  6. 如果不是,它使用printf。将其转换为无符号字符,并使用\\%03u作为格式。

现在很明显,如果意图是将其显示在窗体控件中,并且格式为UTF-8,则打印出各个字符的无符号值不会有帮助。所以我最终决定只是继续Google的MultiByteToWideChar的使用澄清,并且工作 - 除了高价值字符(即亚洲语言字符)。由于我发现Windows功能出错,我最终发现了另一个“手动”的功能。不幸的是,它仍然没有正确处理这些字符。

所以我又看了一遍正在循环的实际const char *,发现它没有被转换的原因 - 是因为别的东西把这些字符改成了63的值 - 问号。这是关于追踪特定“其他”的能力远远超出我的能力的时间,寻求帮助对于本网站的指导方针来说有一个真正的好机会。

因这函数接受,是一个指向联合的typedef,包含用于串对准一个typedef,和一个结构参数 - 它包含绝对零字符数组/指针。但是,它投给了一个。这是如何将该参数转换为函数中的const char *。由于明确地将某些char值更改为63,似乎并不是很有益,我认为它不是c函数的结果,就是不适合(至少在这种情况下)cast。也许如果有人知道这将是结果的情况,并让我知道,我可能会找到有问题的代码。但除此之外,对我而言,期望有人能够在这种情况下提供帮助,这种方式太具体了。

+1

我可能是错的,但我不认为'wchar_t'是非常有用的。我认为它在Unicode存在之前就已经在C标准中,或者刚好在之后。我听说[ICU库](http://userguide.icu-project.org/)是C和C++中Unicode的不错选择。 – yellowantphil 2014-11-24 03:14:09

+0

我不熟悉MSVC或Luac,但是你能解释一下你的程序需要知道什么是文件编码吗? stdlib字符串函数只是将字符串视为一个以null结尾的'char'数组。在大多数情况下,这对UTF-8很好,只要你意识到'strlen'会给你字节长度而不是Unicode码点数量。你需要将UTF-8输入转换为输出中的另一种编码吗? – yellowantphil 2014-11-24 15:45:41

+0

@yantantphil 查看我刚刚添加的问题的Edit2/Update部分,我希望我已经更好地解释了这种情况 - 现在我对它有了更好的理解。 – 2014-11-25 12:47:53

回答

0

使用Win32 API funxtion MultibyteToWideChar你阅读到“宽”的东西,这是UTF-16转换。我认为流类和/或文件流有一个转换模式,这正是你需要的。

wchat_t是在Windows 16位UTF-16代码点。其他平台通常会生成wchar_t 32位并具有不同的约定。