poco 是c++ 一个比较好的库,现在正在学习使用它,碰到一些问题记录在此。

poco版本:poco-1.46-all ,带有数据库的支持模块

操作系统:ubuntu

1.使用poco的MySQL模块连接数据库,中文出现乱码

使用的例子是/poco-1.46-all/Data/samples/sqlite改的MySQL

mysql服务器的test数据库,全部是utf-8格式(数据库是8,表也是utf8),但是使用poco连接后,带中文的字段出现乱码

在命令行中输入

man mysql

MYSQL OPTIONS 节,看见如下设置

--default-character-set=charset_name

           Use charset_name as the default character set for the client and connection.

           A common issue that can occur when the operating system uses utf8 or another multi-byte character set is
that output from the mysql client is formatted incorrectly, due to the fact that the MySQL client uses the
latin1 character set by default. You can usually fix such issues by using this option to force the client
to use the system character set instead. See Section 10.5, “Character Set Configuration”, for more information.

关键就是这里,default-character-set对应的编码要和数据库的test库的编码一致

也就是说default-character-set设置为utf8才对

怎么在poco的mysql模块设置这个编码呢

看poco中的连接mysql代码如下:

    // register MySQL connector
Poco::Data::MySQL::Connector::registerConnector(); // create a session
Session session(SessionFactory::instance().create("MySQL", "user=root;password=888;db=test"));

很自然的先去SessionFactory.cpp看是否有这个设置(Data/src/SessionFactory.cpp),没发现线索。

再去(Data/MySQL/src/)下面看看

先看Connector.cpp这个文件,发现一点点线索

Poco::AutoPtr<Poco::Data::SessionImpl> Connector::createSession(const std::string& connectionString)
{
return Poco::AutoPtr<Poco::Data::SessionImpl>(new SessionImpl(connectionString));
}

就是SessionImpl这个类型,这是真正的实现类

打开同目录下SessionImpl.cpp文件,发现这个类的构造函数中包含对connectionString的解析

std::map<std::string, std::string> options;

解析的结果全部放入上述的options中,

再朝下看,发现

//
// Options
// if (options["compress"] == "true")
{
_mysql.options(MYSQL_OPT_COMPRESS);
}
else if (options["compress"] == "false")
{
// do nothing
}
else if (options["compress"] != "")
{
throw MySQLException("create session: specify correct compress option (true or false) or skip it");
}

还记得最开始的命令行 man mysql不,在 MYSQL OPTIONS 节其中就有一个compress的参数

_mysql.options(MYSQL_OPT_COMPRESS);

上述代码描述了怎么设置compress参数,看一下_mysql的类型

(Data/MySQL/include/Poco/Data/MySQL/sessionImpl.h)

SessionHandle _mysql;

是SessionHandle,然后查看(Data/MySQL/src/),SessionHandle.cpp(或SessionHandle.h)

void SessionHandle::options(mysql_option opt)
{
int res = mysql_options(h, opt, ); if (res != )
{
throw ConnectionException("mysql_options error", h);
}
} void SessionHandle::options(mysql_option opt, bool b)
{
my_bool tmp = b;
int res = mysql_options(h, opt, &tmp); if (res != )
{
throw ConnectionException("mysql_options error", h);
}
}

这里就是设置mysql options参数的地方,看见关键函数mysql_options

去google上查一下 mysql_options

这个http://dev.mysql.com/doc/refman/5.1/en/mysql-options.html

其中发现

MYSQL_OPT_COMPRESS (argument: not used) 
 MYSQL_SET_CHARSET_NAME (argument type: char *)

The name of the character set to use as the default character set. 

很明显现在我需要设置的 MYSQL_SET_CHARSET_NAME这个参数,它是个字符串类型

前面有个 compress的参数,它是bool的

找遍SessionHandle.cpp (.h)只有两个重载

void SessionHandle::options(mysql_option opt)

void SessionHandle::options(mysql_option opt, bool b)

没有设置字符串类型的,那么我们自己动手写了

继续看 http://dev.mysql.com/doc/refman/5.1/en/mysql-options.html

在最下面有例子

MYSQL mysql;
mysql_init(&mysql);
mysql_options(&mysql,MYSQL_OPT_COMPRESS,);
mysql_options(&mysql,MYSQL_READ_DEFAULT_GROUP,"odbc");
mysql_options(&mysql,MYSQL_INIT_COMMAND,"SET autocommit=0");
if (!mysql_real_connect(&mysql,"host","user","passwd","database",,NULL,))
{
fprintf(stderr, "Failed to connect to database: Error: %s\n",
mysql_error(&mysql));
}
mysql_options(&mysql,MYSQL_READ_DEFAULT_GROUP,"odbc");这行就是设置字符串的

现在需要在SessionHandel.h增加一个函数声明
void options(mysql_option opt, char *c);
同时在SessionHandel.cpp实现
void SessionHandle::options(mysql_option opt, char *c)
{ int res = mysql_options(h, opt, c); if (res != )
{
throw ConnectionException("mysql_options error", h);
}
}

在SessionImpl.cpp文件的构造函数,最后如下

//
// Real connect
//
字符串之前增加如下语句
if (options["default-character-set"] != "")
{
_mysql.options(MYSQL_SET_CHARSET_NAME, options["default-character-set"].c_str());
}

最后,把开始的poco中的连接mysql代码改成如下
    // register MySQL connector
Poco::Data::MySQL::Connector::registerConnector(); // create a session
//Session session("user=root;password=888;db=test");
Session session(SessionFactory::instance().create("MySQL", "user=root;password=888;db=test;default-character-set=utf8"));

编译,并查看一下,中文不再乱码了,^_^

使用相同的方法,可以给poco的mysql添加其它设置支持。

c++ poco 使用mysql中文乱码问题的更多相关文章

  1. 解决springmvc+mybatis+mysql中文乱码问题【转】

    这篇文章主要介绍了解决java中springmvc+mybatis+mysql中文乱码问题的相关资料,需要的朋友可以参考下 近日使用ajax请求springmvc后台查询mysql数据库,页面显示中文 ...

  2. 总结--解决 mysql 中文乱码

    首先分析一下导致mysql 中文乱码的原因: 1.建表时使用了latin 编码 2.连接数据库的编码没有指定 3.写入时就已经乱码(这种情况需要自己检查源数据了) 解决方法总结: 1.创建库时指定编码 ...

  3. Servlet、MySQL中文乱码

    1.Servlet中文乱码: 在doPost或doGet方法里,加上以下两行即可: response.setContentType("text/html;charset=UTF-8" ...

  4. php mysql 中文乱码解决方法

    本文章向码农们介绍php mysql 中文乱码解决方法,对码农们非常实用,需要的码农可以参考一下. 从MySQL 4.1开始引入多语言的支持,但是用PHP插入的中文会出现乱码.无论用什么编码也不行 解 ...

  5. windows mysql 中文乱码和中文录入提示太大错误的解决方法

    今天操作mysql的时候很郁闷,因为修改默认字符集搞了半天,终于弄成了(关于如何把windows的默认字符集设置成功,可以参看另一篇博文,最终在mysql中输入show variables like ...

  6. MySQL编程(0) - Mysql中文乱码问题解决方案

    MySQL 5.6 for Windows 解压缩版配置安装: http://jingyan.baidu.com/article/f3ad7d0ffc061a09c3345bf0.html MySQL ...

  7. MySQL及navicat for mysql中文乱码

    转载自:https://www.cnblogs.com/mufire/p/6697994.html 修改完之后记着重启mysql服务,在服务里边重启,即可生效! 全部使用utf8编码 MySQL中文乱 ...

  8. 通过msyql proxy链接mysql中文乱码及session问题

    1.session问题 问题前提:一台机数据库为两个实例,通过不同的socket监听不同端口对外提供服务.不同的站点都访问同一个VIP不同的端口进行访问数据库. 故障现象:一旦有一个站点先用了这个vi ...

  9. 可遇不可求的Question之导入mysql中文乱码解决方法篇

    可遇不可求的Question之导入mysql中文乱码解决方法篇 先 set names utf8;然后 source c:\1.sql ?

随机推荐

  1. jQuery之数组处理函数

    摘要:$.each,$.grep,$.map,$.merge,$.inArray,$.unique,$.makeArray 1. $.each(array, [callback]) 遍历[常用] 解释 ...

  2. windows下的coreseek安装及PHP调用入门

    转载:http://zhan.renren.com/longmensoft?gid=3602888498043096197&checked=true 把我的运行环境简单说一下:windows ...

  3. BZOJ 1975 魔法猪学院(A*求K短路)

    显然每次贪心的走最少消耗的路径即可.那么也就是找出最短路,次短路,,,K短路之后消耗E的能量的最多的路径条数. 也就是裸的A*算法. #include <bits/stdc++.h> us ...

  4. 从原理上搞定编码(二)-- Web编码

    周末宅在家里睡完觉就吃饭,吃完饭接着睡觉,这日子过的实在是没劲啊.明明还有计划中的事情没有做, 为什么就是不想去做呢,这样的生活持续下去,必然会成为一个彻头彻尾的loser.上一篇写的 初识编码 ,这 ...

  5. P2764 最小路径覆盖问题(网络流24题之一)

    题目描述 «问题描述: 给定有向图G=(V,E).设P 是G 的一个简单路(顶点不相交)的集合.如果V 中每个顶点恰好在P 的一条路上,则称P是G 的一个路径覆盖.P 中路径可以从V 的任何一个顶点开 ...

  6. svn和git的区别及适用场景

    svn和git的区别及适用场景 来源 https://blog.csdn.net/wz947324/article/details/80104621 svn的优势: 优异的跨平台支持,对windows ...

  7. 【BZOJ2329】括号修复(Splay)

    [BZOJ2329]括号修复(Splay) 题面 BZOJ 洛谷 题解 本来想着用线段树来写 但是有一个区间翻转 所以不能用线段树了,就只能用平衡树 然后直接\(Splay\)就好了 注意一下几个标记 ...

  8. BZOJ 4864: [BeiJing 2017 Wc]神秘物质 解题报告

    4864: [BeiJing 2017 Wc]神秘物质 Description 21ZZ 年,冬. 小诚退休以后, 不知为何重新燃起了对物理学的兴趣. 他从研究所借了些实验仪器,整天研究各种微观粒子. ...

  9. 跨域通信的解决方案JSONP

    在web2.0时代,熟练的使用ajax是每个前端攻城师必备的技能.然而由于受到浏览器的限制,ajax不允许跨域通信. JSONP就是就是目前主流的实现跨域通信的解决方案. 虽然在在jquery中,我们 ...

  10. 解题:JLOI 2016 侦查守卫

    题面 经典的$cov-unc$树形dp(这词是你自己造的吧=.=) 设$cov[i][j]$表示覆盖完$i$的子树后至少向外再覆盖$j$层的最小代价,$unc[i][j]$表示$i$的子树中还剩下至少 ...