c - 字符编码和类型-C/C++

标签 c visual-c++

也许我有一个错误的想法-但据我了解,宽类型(即wchar_t等)适用于UTF-16 Unicode类型。如果这是正确的,那么我将无法理解对类似问题的大量响应,所有这些都涉及某种形式的wchar_t或其他使用UTF-8的“广泛”转换。

我正在使用MSVC和Unicode构建进行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字节。最初的问题仍然存在,但至少我了解得更多。

编辑2 /更新:
首先,我不确定这部分是否应该作为答案,或者我是否应该结束问题-因此,请随时就此进行教育。

该应用程序最初被编写为控制台应用程序-因此,当需要输出时,它仅使用putchar或printf。但是,这对WinForms应用程序无济于事。因此,我基本上只是通过制作易于管理的等效项来重新路由它。

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

如果常量值是字符串类型,则为处理打印字符串而编写的函数将执行以下操作:


强制转换其参数-指向const char *联合类型的指针
通过索引遍历const char *,将char的值分配给一个int
通过开关/大小写(制表符,换行符等)检查文本中是否有任何转义字符并将其转义
如果失败,则默认情况是使用isprint检查是否为可打印字符
如果是,则使用putchar
如果不是,则使用printf。将其强制转换为无符号字符,并使用\\%03u作为格式。


现在很明显,如果打算将其显示在表单控件中,并且格式为UTF-8,则打印出单个字符的无符号值将无济于事。因此,我最终决定只保留Googling在MultiByteToWideChar上进行一些用法澄清,并且有效-除了高价值字符(即亚洲语言字符)之外。由于我发现所说的Windows函数会出错,所以我最终找到了另一个“手动”执行的错误。不幸的是,它仍然不能正确处理这些字符。

因此,我再次查看了正在循环的实际const char *,发现未进行转换的原因-是因为其他原因将那些char的值更改为63-问号。而这恰恰是在那个时候,追踪那个特定的“其他”远远超出了我的能力范围,寻求帮助很有可能最终导致对本网站的指导过于具体。

由于此函数采用的参数是指向联合typedef的指针,该指针包含用于字符串对齐的typedef和struct-绝对包含零个char数组/指针。但是,它转换为一个。该参数如何在函数中转换为const char *。由于专门将某些char值更改为63,似乎并不十分有益,我在想这要么是c函数的结果,要么是错误建议(至少在这种情况下)强制转换。也许如果有人知道可能的结果,并告诉我,我可能会找到令人讨厌的代码。但是否则,对于我来说太具体了,以至于不能期望有人能够在这种情况下提供帮助。

最佳答案

使用Win32 API函数MultibyteToWideChar将您阅读的内容转换为UTF-16的“宽”。我认为流类和/或FILE流具有转换模式,这正是您所需要的。

wchat_t是Windows中的16位UTF-16代码点。其他平台通常使wchar_t为32位,并具有不同的约定。

关于c - 字符编码和类型-C/C++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27097282/

相关文章:

java - 如何以编程方式控制 IE 托管的 java 小程序?

c - 什么是以及如何解决警告 : format ‘%p’ expects argument of type ‘void *’ , 但参数 2 在打印出来时具有类型 ‘int *’ [-Wformat=]

c++ - 在整数数组中查找前 log(n) 或前 sqt(n) 值

c++ - Boost tread 代码在 VC++ 下编译但在 GCC 下不编译 : how to get better debug info

c++ - 从 stringstream 获取所有内容

使用 gcc 编译 cuda 结果为 : error: ‘threadIdx’ undeclared

C DMA - 使用带有malloced内存的括号

c++ - C/C++ 字符串文字中的未知元字符?

c++ - 多个数组中的排序算法;二进制搜索功能

c++ - x!=x 是实现 std::isnan() 的合法方式吗