此问题之前已被问过,但它的解决方案取决于我不想依赖的Microsoft基础类。基本上我要做的是将Unicode字符转换为它的等效代码点。
以下是使用MFC的解决方案。有没有办法不使用afxwin.h?
#include <afxwin.h>
#include <iostream>
int main() {
using namespace std;
TCHAR myString[50] = _T("عربى");
int stringLength = _tcslen(myString); // <----- edit here
for(int i=0;i<stringLength;i++)
{
unsigned int number =myString[i];
cout<<number<<endl;
}
}
Output:
1593
1585
1576
1609
答案 0 :(得分:3)
如果您的编译器支持它,最简单的方法是将常量字符串写为U"عربى"
。这会为您提供一组char32_t
个字符,其代码点只是用static_cast<uint32_t>()
转换的值。要以标准格式打印它们,只需添加U+
并打印十六进制值。
在C ++ 14编译器上试试这个(我建议将源文件保存为utf-8)。
#include <cstdlib>
#include <iomanip>
#include <iostream>
using std::cout;
int main()
{
constexpr char32_t codepoints[] = U"عربى";
constexpr size_t n = sizeof(codepoints)/sizeof(char32_t);
cout.setf( cout.hex, cout.basefield ); // Output in hex
cout.setf( cout.right, cout.adjustfield ); // Prepending
cout.fill('0'); // leading zeroes
// Fixed: Don’t print the terminating U'\0'.
for ( size_t i = 0; i < n && codepoints[i]; ++i )
cout << "U+" << std::setw(4) << (unsigned long)codepoints[i] << std::endl;
return EXIT_SUCCESS;
}
C ++ STL现在有<codecvt>
,可以从utf-8或utf-16转换为ucs-32。示例代码(来自http://en.cppreference.com/w/cpp/locale/codecvt_utf16):
#include <fstream>
#include <iostream>
#include <string>
#include <locale>
#include <codecvt>
void prepare_file()
{
// UTF-16le data (if host system is little-endian)
char16_t utf16le[4] ={0x007a, // latin small letter 'z' U+007a
0x6c34, // CJK ideograph "water" U+6c34
0xd834, 0xdd0b}; // musical sign segno U+1d10b
// store in a file
std::ofstream fout("text.txt");
fout.write( reinterpret_cast<char*>(utf16le), sizeof utf16le);
}
int main()
{
prepare_file(); // open as a byte stream
std::wifstream fin("text.txt", std::ios::binary);
// apply facet
fin.imbue(std::locale(fin.getloc(), new std::codecvt_utf16<wchar_t, 0x10ffff, std::little_endian>));
for (wchar_t c; fin.get(c); )
std::cout << std::showbase << std::hex << c << '\n';
}
C11和C ++ 11还具有在多字节utf-8和utf-16以及宽字符串之间进行转换的功能(来自这里:http://en.cppreference.com/w/c/string/multibyte/mbrtoc32)。 mbstowcs()
功能也可能是相关的。
#include <stdio.h>
#include <locale.h>
#include <string.h>
#include <uchar.h>
#include <assert.h>
mbstate_t state;
int main(void)
{
setlocale(LC_ALL, "en_US.utf8");
char *str = u8"z\u00df\u6c34\U0001F34C"; // or u8"zß水"
printf("Processing %zu bytes: [ ", strlen(str));
for(char* p = str; *p; ++p)
printf("%#x ", (unsigned char)*p); puts("]");
char32_t c32;
char *ptr = str, *end = str + strlen(str);
int rc;
while(rc = mbrtoc32(&c32, ptr, end - ptr, &state)) {
printf("Next UTF-32 char: %#x obtained from ", c32);
assert(rc != -3); // no surrogate pairs in UTF-32
if(rc > 0) {
printf("%d bytes [ ", rc);
for(int n = 0; n < rc; ++n)
printf("%#x ", (unsigned char)ptr[n]); puts("]");
ptr += rc;
}
}
}
虽然这些示例使用十六进制代码,但C11和C ++ 11支持Unicode字符串(http://en.cppreference.com/w/cpp/language/string_literal)。由于上面示例中的Unicode是utf-16le,因此将其作为常量写入的标准方法是u"عربى"
。您也可以使用U"عربى"
将其编码为ucs-32,而不必进行任何代理对转换。
答案 1 :(得分:0)
简单,阅读unicode规范并注意unicode标量,代理和补充字符,自己扩展字形集群。
或者您可以使用今天大多数操作系统中包含的IBM ICU库。
如果问题只是MFC头文件,您可以定义UNICODE,_UNICODE并包含tchar.h。