【问题标题】:How to safely and portably input and check for accent characters如何安全便携地输入和检查重音字符
【发布时间】:2017-06-27 11:23:01
【问题描述】:

如果不知道输入的locale 是哪个locale,那么推荐的读取某些可能包含特殊字符(例如重音)的用户输入的方法是什么。

如何安全地比较这个用户输入的一个字符,如果它是一个特殊的字符,我需要以某种方式处理?

这是说明意图的示例代码:

#include <iostream>
using namespace std;

int main() {
    char txt[10];
    cin.getline(txt, sizeof(txt));
    if(txt[0] == 'á')
        cout << "Special character found\n";
}

问题是:

warning: multi-character character constant [-Wmultichar]
     if(txt[0] == 'á')
                  ^

如果我使用L'á' 作为宽字符文字,那么它将不匹配,因为输入不是宽字符。

如果我也使用wchar_twcin.getline 来获取宽字符的用户输入,那么它可能适用于某些系统,但可能不适用于其他系统,具体取决于环境和区域设置。

如何安全、便携地解决这个问题?谢谢!

【问题讨论】:

  • 您可能需要考虑使用像ICU这样的unicode库
  • 最好的方法,还是我们最喜欢的?我在内部使用 UTF8 进展顺利,在 Windows 中,我必须来回转换为 UTF-16 以进行 UI 显示和输入,但这是值得的。我专门使用boost::locale::conv::utf_to_utf 进行转换。

标签: c++ utf-8 locale non-ascii-characters wchar-t


【解决方案1】:

如果你们都不知道自己的语言环境并且必须使您的解决方案具有可移植性,那么恐怕没有标准的 C++ 解决方案。而且我不确定它是否会存在,考虑到使用 UTF-16 的 Windows。 因此,如果您需要“开箱即用的解决方案”,检查NathanOliver's comment 中提到的库可能是有意义的。

话虽如此,尽管 Unicode 支持仍然是 C++ 的一个痛点(而且我在 2017 年写下这些话真的很遗憾),但 C++11 还是有一些改进。

因此,如果您可以选择手动转换,您可能会从它的一些优点中获益。

例如,这是一个有效的 C++11 代码。

unsigned char euroUTF8[] = { 0xE2, 0x82, 0xAC, 0x00 }; // Euro sign UTF8

wstring_convert<codecvt_utf8<wchar_t>> converter_UTF8_wchar;
wstring euroWideStr = converter_UTF8_wchar.from_bytes((char*)euroUTF8);
wcout << euroWideStr << endl;

string euroNarrowStr = converter_UTF8_wchar.to_bytes(euroWideStr);
cout << euroNarrowStr << endl;

更多上下文检查this article

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-06-27
    • 1970-01-01
    • 2012-09-25
    • 2011-11-10
    • 1970-01-01
    • 1970-01-01
    • 2010-12-25
    相关资源
    最近更新 更多