MFC新手:如何使用"FindOneOf()"判断字符是否为十六进制
MFC newbie: how to determine if a character is hexadecimal using "FindOneOf()"
我是 MFC 的新手,我需要做一些听起来非常简单的事情:确定字符串是否仅包含十六进制字符。
为此,我浏览了字符串(它是一个 CString
)并使用 FindOneOf()
方法验证所有字符,如下所示:
int iTest = CString(pszText[i]).FindOneOf((LPCWSTR)"0123456789ABCDEFabcdef");
由于某些奇怪的原因,我总是得到 -1
结果。
我做错了什么?
P.s.1 我不喜欢使用 SpanIncluding()
方法,我发现 FindOneOf()
非常可读,但我不知道如何使用它。
P.s.2 同样简单 STL
似乎不起作用:我尝试使用 std::isxdigit(pszText[i])
但为了让它起作用,我需要包含 <locale>
然后这个函数要求第二个参数,在我要检查的字符旁边,那里不允许使用 null
-指针(std::isxdigit(pszText[i], nullptr)
不起作用)。
你的代码有几个问题:
这是错误的:
int iTest = CString(pszText[i]).FindOneOf(LPCWSTR)"0123456789ABCDEFabcdef");
应该是:
int iTest = CString(pszText[i]).FindOneOf(L"0123456789ABCDEFabcdef");
强制转换只会让编译器相信 "0123..."
是一个宽字符串,但事实并非如此。需要使用L
前缀表示该字符串为宽字符串
但即便如此,您的算法也无法正常工作,因为 FindOneOf
只会找到参数中任何字符的第一次出现。
示例:
int iTest = CString(L"Z223Zbc").FindOneOf(L"0123456789ABCDEFabcdef");
"Z223Zbc"
显然不是十六进制字符串,但是 iTest
将包含 1 因为 "Z223Zbc"
作为 "0123456789ABCDEFabcdef"
的一部分的第一个字符是 '2'
那是在位置 1.
如果要测试的字符串不包含 any 十六进制字符,例如 "xyz"
.[=27,iTest
将仅包含 -1 =]
因此这个解决方案是合适的:
#include <cwctype>
...
WCHAR string[] = L"123abcX";
bool ishexstring = true; // assume the string is a hex string
for (int i = 0; ; i++)
{
WCHAR c = string[i];
if (c == 0)
break; // end of string => we exit the looop
if (!std::iswxdigit(c))
{
ishexstring = false; // c is no hex digit
break; // exit loop
}
}
这个算法应该放在一个函数中,但我把它留作 reader.
的练习。
使用SpanIncluding
的解决方案(效率较低,因为我们需要构建一个临时的CString
):
bool ishexstring = CString(string).SpanIncluding(L"0123456789ABCDEFabcdef") == str;
我是 MFC 的新手,我需要做一些听起来非常简单的事情:确定字符串是否仅包含十六进制字符。
为此,我浏览了字符串(它是一个 CString
)并使用 FindOneOf()
方法验证所有字符,如下所示:
int iTest = CString(pszText[i]).FindOneOf((LPCWSTR)"0123456789ABCDEFabcdef");
由于某些奇怪的原因,我总是得到 -1
结果。
我做错了什么?
P.s.1 我不喜欢使用 SpanIncluding()
方法,我发现 FindOneOf()
非常可读,但我不知道如何使用它。
P.s.2 同样简单 STL
似乎不起作用:我尝试使用 std::isxdigit(pszText[i])
但为了让它起作用,我需要包含 <locale>
然后这个函数要求第二个参数,在我要检查的字符旁边,那里不允许使用 null
-指针(std::isxdigit(pszText[i], nullptr)
不起作用)。
你的代码有几个问题:
这是错误的:
int iTest = CString(pszText[i]).FindOneOf(LPCWSTR)"0123456789ABCDEFabcdef");
应该是:
int iTest = CString(pszText[i]).FindOneOf(L"0123456789ABCDEFabcdef");
强制转换只会让编译器相信 "0123..."
是一个宽字符串,但事实并非如此。需要使用L
前缀表示该字符串为宽字符串
但即便如此,您的算法也无法正常工作,因为 FindOneOf
只会找到参数中任何字符的第一次出现。
示例:
int iTest = CString(L"Z223Zbc").FindOneOf(L"0123456789ABCDEFabcdef");
"Z223Zbc"
显然不是十六进制字符串,但是 iTest
将包含 1 因为 "Z223Zbc"
作为 "0123456789ABCDEFabcdef"
的一部分的第一个字符是 '2'
那是在位置 1.
"xyz"
.[=27,iTest
将仅包含 -1 =]
因此这个解决方案是合适的:
#include <cwctype>
...
WCHAR string[] = L"123abcX";
bool ishexstring = true; // assume the string is a hex string
for (int i = 0; ; i++)
{
WCHAR c = string[i];
if (c == 0)
break; // end of string => we exit the looop
if (!std::iswxdigit(c))
{
ishexstring = false; // c is no hex digit
break; // exit loop
}
}
这个算法应该放在一个函数中,但我把它留作 reader.
的练习。使用SpanIncluding
的解决方案(效率较低,因为我们需要构建一个临时的CString
):
bool ishexstring = CString(string).SpanIncluding(L"0123456789ABCDEFabcdef") == str;