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;