将wchar_t转换为int

时间:2011-05-20 07:29:53

标签: c++ wchar-t

如何将wchar_t'9')转换为int9)形式的数字?

我有以下代码,我会检查peek是否为数字:

if (iswdigit(peek)) {
    // store peek as numeric
}

我可以减去'0'还是有一些我应该担心的Unicode细节?

5 个答案:

答案 0 :(得分:5)

查看atoi类函数:http://msdn.microsoft.com/en-us/library/hc25t012(v=vs.71).aspx

特别是_wtoi(const wchar_t *string);似乎是您正在寻找的。但是,你必须确保你的wchar_t被正确地终止,所以尝试这样的事情:

if (iswdigit(peek)) {
    // store peek as numeric
    wchar_t s[2];
    s[0] = peek;
    s[1] = 0;
    int numeric_peek = _wtoi(s);
}

答案 1 :(得分:5)

如果问题仅涉及'9'(或其中一个罗马人 数字),只需减去'0'就是正确的解决方案。如果 你担心iswdigit返回的任何事情 然而,非零,问题可能要复杂得多。该 standard表示iswdigit返回非零值 参数是“十进制数字宽字符代码[在当前 当地]“。这是模糊的,并留给现场 确切地定义了什么意思。在“C”语言环境或“Posix” locale,“Posix”标准,至少,保证只有 罗马数字0到9被认为是十进制数字(如果 我理解正确),所以如果你在“C”或“Posix” locale,只需减去'0'即可。

据推测,在Unicode语言环境中,这可能是任何字符 它具有一般类别Nd。有很多 这些。最安全的解决方案就是创造一些东西 喜欢(这里有静态生命周期的变量):

wchar_t const* const digitTables[] =
{
    L"0123456789",
    L"\u0660\u0661\u0662\u0663\u0664\u0665\u0666\u0667\u0668\u0669",
    // ...
};

//!     \return
//!         wch as a numeric digit, or -1 if it is not a digit
int asNumeric( wchar_t wch )
{
    int result = -1;
    for ( wchar_t const* const* p = std::begin( digitTables );
            p != std::end( digitTables ) && result == -1;
            ++ p ) {
        wchar_t const* q = std::find( *p, *p + 10, wch );
        if ( q != *p + 10 ) {
            result = q - *p;
    }
    return result;
}

如果你走这条路:

  1. 你肯定想下载 来自Unicode联盟的UnicodeData.txt文件 (“Uncode Character Database” - 此页面包含两个Unicode数据的链接 文件和对其中使用的编码的探索),和
  2. 可能会写一个这个文件的简单解析器来解压缩 信息自动(例如,当有新版本的时候) Unicode) - 该文件专为简单的程序设计 解析。
  3. 最后,请注意基于ostringstream和。的解决方案 istringstream(包括boost::lexical_cast)不会 工作,因为流中使用的转换仅定义为 使用罗马数字。 (另一方面,它可能是 合理地将您的代码限制为罗马数字。在 在哪种情况下,测试成为if ( wch >= L'0' && wch <= L'9' ), 转换只需减去L'0' - 总是假设宽字符的原生编码 你的编译器中的常量是Unicode(这种情况,我很漂亮 确定,VC ++和g ++)。或者只是确保语言环境 “C”(或“Posix”,在Unix机器上)。

    编辑:我忘了提一下:如果你正在进行任何严肃的Unicode编程,那么你 应该研究ICU。处理Unicode 正确是非常重要的,他们已经有很多功能 实现。

答案 2 :(得分:1)

您可以使用boost::lexical_cast

const wchar_t c = '9';
int n = boost::lexical_cast<int>( c );

答案 3 :(得分:1)

尽管有MSDN documentation,但一个简单的测试表明,不仅游侠L'0'-L'9'会回归真实。

for(wchar_t i = 0; i < 0xFFFF; ++i)
{
    if (iswdigit(i))
    {
        wprintf(L"%d : %c\n", i, i);
    }
}

这意味着L'0'减法可能无法正常工作。

答案 4 :(得分:0)

对于大多数用途,您只需减去“0”的代码即可。

然而,关于Unicode numerials的维基百科文章提到十进制数字用23个单独的块表示(包括两次阿拉伯语)。

如果你不担心,那么只需减去代码'0'。