C++ 如何使用Win32 WCHAR执行字符串操作

C++ 如何使用Win32 WCHAR执行字符串操作,c++,unicode,unicode-string,wchar-t,C++,Unicode,Unicode String,Wchar T,我有一个win32项目,在该项目中,我试图使用自定义函数编辑WCHAR字符串的字符 我知道这代表宽字符,是Unicode,但是我不完全理解编码是如何工作的。例如,我知道UTF-8也支持Unicode,但它与WCHAR相同吗 我以为这根绳子看起来像 00 43 00 4f 00 44 00 45 00 00 C O D E \0 对于复制,只要假设字符串的长度是原来的两倍就可以了。但是,我在搜索角色时会出错,例如: for(int i = wcslen(in

我有一个win32项目,在该项目中,我试图使用自定义函数编辑WCHAR字符串的字符

我知道这代表宽字符,是Unicode,但是我不完全理解编码是如何工作的。例如,我知道UTF-8也支持Unicode,但它与WCHAR相同吗

我以为这根绳子看起来像

00 43 00 4f 00 44 00 45 00 00
    C     O     D     E    \0
对于复制,只要假设字符串的长度是原来的两倍就可以了。但是,我在搜索角色时会出错,例如:

for(int i = wcslen(inStr) - 2; i >= 0; i--) {
    WCHAR current[] = {inStr[i], inStr[i + 1], 0, 0};
    if(current == _T("/")) {
        pos = i;
        break;
    }
}
产生一些损坏的错误。我是不是把事情弄得太复杂了?我知道可能有很多函数可以做到这一点,但我想了解它是如何工作的,这样我就可以编写高效的代码。谢谢

简短的回答 您遇到的具体问题是
current[n]
是数组中的第n个元素,而不是数组的第n个字节。执行诸如
current+n
之类的指针运算也会在
current
指向的元素之后给出第n个元素。如果您声明了一个数组
int
double
、一些
struct
或其他任何内容,则情况也是如此

因此,当您声明一个数组
wchar\u t a[]=L“!”
,然后取
wcslen(a)
,您将得到数组中宽字符的计数,1。如果您试图设置
i=wcslen(a)-2a[i]
i
将为-1,这是一个严重的错误

更长的解释 在Windows上,
WCHAR
是标准类型
WCHAR\u t
的别名。你不说你是用C还是C++写的。在C标准库中有许多函数可以处理宽字符串,如
。C++标准库中有所有这些,以及<>代码> STD::WSCOR> <代码> >代码> >代码>和宽字符流,包括“代码> STD::WcOUT , STD::WCIN < /C>和 STD::WCLSR (虽然Windows不完全支持它们)。大多数Windows API函数也可以接受宽字符串。宽字符串的标准类型是
wchar\u t*
,但
wchar*
LPWSTR
在Visual Studio的现代版本中,默认情况下,
TCHAR*
LPTSTR
也可以工作

在Windows上,宽字符是小尾端UTF-16。这是不可移植的,但是,
WCHAR
。在其他一些系统中,宽字符可以是大端UTF-16,也可以是大端或小端UTF-32。在C中,标准类型
char16\u t
char32\u t
中定义。在C++中,它们被内置到语言中。如果您试图将
char16\u t*
传递给需要
wchar\u t*
的函数,则如果没有强制转换,或者在Windows以外的目标上,它将无法工作

UTF-8是一种存储与七位ASCII向后兼容的Unicode代码点的方法。UTF-8是UTF-16或UTF-32的替代表示形式。UTF-8字符串将存储在
无符号字符
字符
的数组中,一个Unicode码点可能需要几个字节来存储它。实际上,由于存在代理项对,Unicode代码点也可能需要两个UTF-16对象来对其进行编码。有时使用不同的表示法比较方便(UTF-16LE是Windows ABI所期望的,也是一些库(如ICU和QT)在内部使用的,UTF-32是保证所有Unicode字符都适合单个元素的唯一表示法),但我的建议是尽可能使用UTF-8,必要时使用其他编码

可能的解决办法 如果要反向读取宽字符串,可以尝试以下方法:

int i = wcslen(inStr); // Could be 0.

if (i > 0) { // Don't read one element past the start of the array.
  do {
    --i;
  } while ( i > 0 && inStr[i] != L'/' );
}

/* When we reach this line, i is either 0 or the index of the last slash
 * in inStr, which could also be 0.  We can test whether inStr[i] == L'/' or
 * write an if() within our loop to do something more complicated.
 */

谢谢,这太完美了。我用的是C++。我明白你的意思了,我试着用unicode表示法对字节数组进行操作,但wchar_____t本身就是一个16位字符。所以L'/'只返回一个宽的wchar\t。我想知道,在UTF-8中,字符是如何链接在一起的?最后一位用于链接每个字节吗?在线查找UTF-8上的信息很容易,但简短的回答是:如果UTF-8字节的高位为0,则它是ASCII字符。高于127的任何Unicode代码点都由两到四个字节的序列表示。以110、1110或11110开头的字节是多字节序列的第一个字节,以10开头的字节延续多字节序列。这使得UTF-8向后兼容ASCII,易于自动检测和检查有效性,不受endianness的影响,并且对于许多语言都很紧凑。不幸的是,Windows NT在UTF-8之前就推出了,所以Windows被它所拥有的东西卡住了。谢谢。这使情况变得明朗了许多。我理解这是“谷歌IT”问题之一,这就是为什么我被否决了,但是有时在这些特定的问题上,“Unicode编码”并不能真正给我我所需要的,请在以后的C++问题中添加<代码> C++ +/Code >标签。