C++ 数据验证:库与实际方法概览
数据验证是开发可靠 C++ 软件的关键方面之一。正确检查输入数据可以防止运行时错误、漏洞和未定义行为。与动态类型语言不同,C++ 要求开发者显式控制类型和格式。在本文中,我们将探讨手动方法和专用库,这些库可以简化验证过程。
1. 手动验证:基本技巧
最简单的方法是使用条件语句检查数据。这种方法适用于小型项目,但会很快变得冗长。
#include <iostream>#include <string>#include <cctype>
bool validateEmail(const std::string& email) { if (email.empty()) return false; size_t atPos = email.find('@'); if (atPos == std::string::npos || atPos == 0) return false; size_t dotPos = email.rfind('.'); if (dotPos == std::string::npos || dotPos <= atPos + 1) return false; if (dotPos == email.length() - 1) return false; return true;}
int main() { std::string testEmail = "user@example.com"; std::cout << (validateEmail(testEmail) ? "Valid" : "Invalid") << std::endl; return 0;}缺点:维护复杂、代码重复、缺乏统一接口。
2. libvalidate 库
libvalidate 是一个轻量级库,用于 C++17 及更高版本中的声明式数据验证。它允许以链式风格描述验证规则,类似于 PHP 或 Python 中的验证器。
安装
该库以 header-only 形式分发。只需将 validate.hpp 复制到项目中,或通过 CMake 引入:
# 示例 FetchContentinclude(FetchContent)FetchContent_Declare(libvalidate GIT_REPOSITORY https://github.com/username/libvalidate.git GIT_TAG v1.0.0)FetchContent_MakeAvailable(libvalidate)使用示例
#include "validate.hpp"#include <iostream>#include <string>
int main() { using namespace validate;
// 验证数字(年龄) int age = 25; auto ageResult = check(age) .min(18, "年龄必须不小于18岁") .max(120, "年龄必须不大于120岁");
if (!ageResult.valid()) { std::cerr << ageResult.error() << std::endl; }
// 验证字符串(密码) std::string password = "P@ssw0rd"; auto passResult = check(password) .minLength(8, "密码长度至少为8个字符") .matches(R"((?=.*[A-Z])(?=.*[a-z])(?=.*\\d).*)", "密码必须包含大写字母、小写字母和数字");
if (!passResult.valid()) { std::cerr << passResult.error() << std::endl; }
// 组合对象验证 struct User { std::string name; int age; std::string email; };
User user{"Alice", 30, "alice@example.com"}; auto userResult = check(user) .field(&User::name, "name") .minLength(2) .maxLength(50) .field(&User::age, "age") .range(18, 100) .field(&User::email, "email") .email(); // 内置 email 验证
if (!userResult.valid()) { for (const auto& err : userResult.errors()) { std::cerr << err.field << ": " << err.message << std::endl; } }
return 0;}特点:
- 支持内置规则:
min、max、range、email、regex、notEmpty。 - 能够创建