来自Unicode字符的码点

Codepoint from Unicode Character?

本文关键字:字符 Unicode 来自      更新时间:2023-10-16

这个问题以前已经问过了,但它的解决方案依赖于我不想依赖的Microsoft Foundation class。基本上我想做的是把一个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

更新

如果你的编译器支持它,最简单的方法可能是把你的常量字符串写成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''.
  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"zu00dfu6c34U0001F34C"; // 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,而不必进行任何代理对转换。

很容易,阅读unicode规范,并照顾unicode标量,代理和补充字符,扩展字形集群自己。

或者您可以使用IBM ICU库,它包含在当今大多数操作系统中。

如果问题只是MFC头文件,您可以定义UNICODE, _UNICODE并包括tchar.h.