如何正确实现 std::all_of 函数来验证字符串的一部分?

How do i implement std::all_of function correctly to verify part of a string?

我正在尝试验证字符串的一部分(在我的例子中,车牌总共有 7 个字符,看起来像 "000 ABC"),以便它符合特定格式。在这里,我使用 std::all_of() 检查函数中传递的参数是否以 3 个数字开头并以 3 个字母结尾,中间有一个 space。我举的代码片段是这样的:

#include <algorithm> // <---- line 8
. . .
. . .

bool validateLicensePlate (const std::string& p_license_plate)
{
    int plate_length = p_license_plate.length();

    if (plate_length == 7 && p_license_plate[3] == ' ')
    {
        if (std::all_of(p_license_plate[0], p_license_plate[2], isdigit))   // <---- line 20
        {
            if (std::all_of(p_license_plate[4], p_license_plate[6], isalpha))
            {
                return true;
            }
            else
            {
                return false;
            }
        }
. . .
. . .
}

但是当我尝试编译程序时,我得到这个错误:

In file included from /usr/include/c++/7/algorithm:62:0,
                 from ../src/validationFormat.cpp:8:
/usr/include/c++/7/bits/stl_algo.h: In instantiation of ‘_InputIterator std::__find_if_not(_InputIterator, _InputIterator, _Predicate) [with _InputIterator = char; _Predicate = __gnu_cxx::__ops::_Iter_pred]’:
/usr/include/c++/7/bits/stl_algo.h:566:32:   required from ‘_IIter std::find_if_not(_IIter, _IIter, _Predicate) [with _IIter = char; _Predicate = int (*)(int) throw ()]’
/usr/include/c++/7/bits/stl_algo.h:509:40:   required from ‘bool std::all_of(_IIter, _IIter, _Predicate) [with _IIter = char; _Predicate = int (*)(int) throw ()]’
../src/validationFormat.cpp:20:76:   required from here
/usr/include/c++/7/bits/stl_algo.h:173:32: error: no matching function for call to ‘__iterator_category(char&)’
        std::__iterator_category(__first));
        ~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~

我做错了什么?

您必须向 std::all_of 提供迭代器,而不是该位置的值。

在这种情况下,迭代器只是指向其中一个字符串元素的指针,例如 &s[0] 是指向 s 中第一个元素的迭代器,而 s[0] 是元素。你要提供前者,而不是后者。

话虽如此,这里是一个示例,不使用地址语法,而是使用 std::string::iterator 并使用 begin()/end() 并使用偏移量来表示迭代器使用:

#include <iostream>
#include <cctype>
#include <algorithm>
#include <string>

bool isValidLicense(const std::string& s)
{
   // lambdas for checking a digit character
   auto isdig = [] (char ch) { return std::isdigit(static_cast<unsigned char>(ch)); };

   // lambda for checking if an alpha character
   auto islet = [] (char ch) { return std::isalpha(static_cast<unsigned char>(ch)); };

   // return if the string matches all the criteria shown
   return s.length() == 7 &&   // must be 7 characters
          s[3] == ' ' &&      // fourth character is a space
          std::all_of(s.begin(), s.begin() + 3, isdig) &&  // first 3 are all digits
          std::all_of(s.begin() + 4, s.end(), islet);  // last 3 digits are letters
}

int main()
{
   std::cout << isValidLicense("abc 123") << "\n" << isValidLicense("123 abc");
}

输出:

0
1

如果您使用 "address-of" 版本,也会达到同样的效果:

   return s.length() == 7 &&   // must be 7 characters
          s[3] == ' ' &&      // fourth character is a space
          std::all_of(&s[0], &s[3], isdig) &&  // first 3 are all digits
          std::all_of(&s[4], &s[7], islet);  // last 3 digits are letters