将wchar_t转换为整数

Convert wchar_t to int

本文关键字:整数 转换 wchar      更新时间:2023-10-16

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

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

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

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

如果问题只涉及'9'(或罗马人之一)数字),只需减去'0'是正确的解决方案。 如果您关心iswdigit返回的任何事情然而,非零,问题可能要复杂得多。 这标准表示,iswdigit如果参数是"十进制数字宽字符代码 [在当前本地]"。 这是模糊的,并将其留给区域设置准确定义含义。 在"C"区域设置或"Posix"中语言环境,至少"Posix"标准保证只有罗马数字 0 到 9 被视为十进制数字(如果我理解正确),所以如果你在"C"或"Posix"中区域设置,只需减去"0"应该有效。

据推测,在 Unicode 区域设置中,这将是任何字符具有一般类别Nd。 有许多这些。 最安全的解决方案就是简单地创造一些东西喜欢(此处具有静态生存期的变量):

wchar_t const* const digitTables[] =
{
    L"0123456789",
    L"u0660u0661u0662u0663u0664u0665u0666u0667u0668u0669",
    // ...
};
//!     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文件("解码字符数据库"—此页面包含指向 Unicode 数据的链接文件和其中使用的编码的说明),以及
  2. 可能会编写此文件的简单解析器来提取自动信息(例如,当有新版本时Unicode)- 文件专为简单的编程而设计解析。

最后,请注意,基于 ostringstreamistringstream(包括boost::lexical_cast)不会工作,因为流中使用的转换定义为仅使用罗马数字。 (另一方面,它可能是将您的代码限制为罗马数字是合理的。 在在这种情况下,测试变得if ( wch >= L'0' && wch <= L'9' ),转换是通过简单地减去L'0'来完成的——始终假设宽字符的本机编码编译器中的常量是 Unicode(这种情况,我很漂亮当然,VC++ 和 G++)。 或者只是确保区域设置是"C"(或"Posix",在Unix机器上)。

编辑:我忘了提:如果你正在做任何严肃的Unicode编程,你应该检查重症监护室。 处理 Unicode正确是非常不平凡的,而且它们已经有很多功能实现。

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

尤其是_wtoi(const wchar_t *string);似乎是您正在寻找的。但是,您必须确保您的wchar_t正确终止 null,因此请尝试以下操作:

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

boost::lexical_cast

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

MSDN 文档,但一个简单的测试表明,不仅游侠 L'0'-L'9' 返回 true。

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

这意味着 L'0' 减法可能不会像您预期的那样工作。

在大多数情况下,

您只需减去"0"的代码即可。

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

如果您不担心这一点,那么只需减去"0"的代码即可。