如何将wchar_t
('9'
)转换为int
(9
)形式的数字?
我有以下代码,我会检查peek
是否为数字:
if (iswdigit(peek)) {
// store peek as numeric
}
我可以减去'0'
还是有一些我应该担心的Unicode细节?
答案 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;
}
如果你走这条路:
UnicodeData.txt
文件
(“Uncode Character
Database” - 此页面包含两个Unicode数据的链接
文件和对其中使用的编码的探索),和最后,请注意基于ostringstream
和。的解决方案
istringstream
(包括boost::lexical_cast
)不会
工作,因为流中使用的转换仅定义为
使用罗马数字。 (另一方面,它可能是
合理地将您的代码限制为罗马数字。在
在哪种情况下,测试成为if ( wch >= L'0' && wch <= L'9' )
,
转换只需减去L'0'
-
总是假设宽字符的原生编码
你的编译器中的常量是Unicode(这种情况,我很漂亮
确定,VC ++和g ++)。或者只是确保语言环境
“C”(或“Posix”,在Unix机器上)。
答案 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'。