一点关于达梦VARCHAR(255)
的理解。
某涉及达梦数据库的项目中,从达梦数据库取出来数据后需要和本地的std::unordered_map
比对,来和本地平台的enum class
属性的类型进行匹配,但是std::string
之间比对出现了问题,通过
for (char c : str)
std::cout << (int)c << " ";
std::cout << std::endl;
输出字符串的每个字符的 ASCII 值,发现ASCII 值后半部分不相同,大概率是达梦数据库针对VARCHAR(255)类型数据兼容性没有做到位,导致ODBC取出来字符串有隐藏的字符。
解决方案如下。
建立StringComparator
类,处理std::string
比对的情况。
#include <string>
#include <algorithm>
#include <cctype>
class StringComparator {
public:
enum CompareMode {
CaseSensitive, // 区分大小写
IgnoreCase, // 忽略大小写
IgnoreAllSpaces, // 忽略所有空白
IgnoreCaseAndSpaces // 忽略大小写和所有空白
};
// 构造函数,设置比较模式
StringComparator(CompareMode mode = IgnoreCaseAndSpaces)
: m_mode(mode) {}
// 设置比较模式
void setMode(CompareMode mode) { m_mode = mode; }
// 执行比较
bool compare(const std::string& a, const std::string& b) const {
std::string sa = trim(a);
std::string sb = trim(b);
switch (m_mode) {
case CaseSensitive:
return sa == sb;
case IgnoreCase:
return toLower(sa) == toLower(sb);
case IgnoreAllSpaces:
return removeSpaces(sa) == removeSpaces(sb);
case IgnoreCaseAndSpaces:
return toLower(removeSpaces(sa)) == toLower(removeSpaces(sb));
default:
return sa == sb;
}
}
private:
CompareMode m_mode;
// 工具函数
static std::string trim(const std::string& s) {
auto start = std::find_if_not(s.begin(), s.end(), ::isspace);
auto end = std::find_if_not(s.rbegin(), s.rend(), ::isspace).base();
return (start < end ? std::string(start, end) : "");
}
static std::string toLower(const std::string& s) {
std::string result = s;
std::transform(result.begin(), result.end(), result.begin(), ::tolower);
return result;
}
static std::string removeSpaces(const std::string& s) {
std::string result;
std::copy_if(s.begin(), s.end(), std::back_inserter(result),
[](char c){ return !std::isspace(c); });
return result;
}
};
应用:
StringComparator cmp(StringComparator::IgnoreCaseAndSpaces);
std::string str1 = " Hello World ";
std::string str2 = "hello world";
if (cmp.compare(str1, str2)) {
std::cout << "good match" << std::endl;
} else {
std::cout << "bad match" << std::endl;
}
// 也可以随时切换比较模式
cmp.setMode(StringComparator::CaseSensitive);
if (cmp.compare(str1, str2)) {
std::cout << "Strict equality" << std::endl;
}