在新项目POC时,AI助手快速生成的验证项目,后台C++ OTL实现快速SQL业务代码,通过ODBC连接PostgreSQL,发现C++控制台输出cout 乱码,DBeaver或Postgres后台psql查询数据乱码,引发问题多方排查未解决,特此留痕。供参考。
源码下载:参考附件。
项目背景:C++ OTL模板业务代码,psqlODBC驱动,Postgres后台部署在Ubuntu2404,ver18.3
其中C++项目CMakelists.txt 设置:add_definitions(-DUNICODE -D_UNICODE)
main.cpp 使用utf8编码,设置控台输出utf8:
在:
main(){
#ifdef _WIN32
SetConsoleOutputCP(CP_UTF8);
#endif
// todo...
}
一、检查Postgres后台,客户端字符集:
部署postgres服务端Ubuntu登录psql后执行:
select name, setting, context from pg_settings where name like '%encoding%';
二、检查代码层控制台输出
2.1 cout << "测试中文";
预期:显示正常“测试中文”
2.2 设置ODBC连接串DSN:关键必须加“ConnSettings=SET CLIENT_ENCODING TO 'UTF8';”
无论是使用DRIVER={PostgreSQL Unicode(x64)} 还是 DRIVER={PostgreSQL ANSI(x64)}
参考DSN:
// 使用Unicode驱动 const string CONNECTION_STR_W = "DRIVER={PostgreSQL Unicode(x64)};" "SERVER=192.168.1.15;" "PORT=5432;" "DATABASE=postgres;" "UID=postgres;" "PWD=tlox@2026;" "ConnSettings=SET CLIENT_ENCODING TO 'UTF8';"; // "ClientEncoding=UTF-8"; // 使用ANSI驱动 const string CONNECTION_STR_A = "DRIVER={PostgreSQL ANSI(x64)};" "SERVER=192.168.1.15;" "PORT=5432;" "DATABASE=postgres;" "UID=postgres;" "PWD=tlox@2026;" "ConnSettings=SET CLIENT_ENCODING TO 'UTF8';"; // "ClientEncoding=UTF-8" // "Debug=1"; // ANSI 驱动可以指定字符集三、结果验证:
参考步骤2中设置DSN串包含:ConnSettings=SET CLIENT_ENCODING TO 'UTF8'; 时,Postgres服务端查询数据正常,DBeaver查询数据正常
反例验证:
注释或删除DSN中包含:ConnSettings=SET CLIENT_ENCODING TO 'UTF8';
重新编译运行,运行效果:
控制台输出正常:
数据库后台数据(乱码):
工具查询数据(乱码):
再次验证:DSN加上:ConnSettings=SET CLIENT_ENCODING TO 'UTF8';
结果:恢复正常。
切换驱动方式验证:默认是ANSI,即 CONNECTION_STR_A
切换到:CONNECTION_STR_W,即Unicode,效果类型,
关键还是:ConnSettings=SET CLIENT_ENCODING TO 'UTF8'; 影响最后数据。