[问题] VC++ 字符集"Unicode"下使用MySQL

楼主: chingyue (ChingYue)   2017-06-16 18:05:55
开发平台(Platform): (Ex: Win10, Linux, ...)
win7(win10)
编译器(Ex: GCC, clang, VC++...)+目标环境(跟开发平台不同的话需列出)
VC++(2013)
额外使用到的函数库(Library Used): (Ex: OpenGL, ...)
MySQL API
问题(Question):
各位前辈大家好
之前小弟写了一支程式
使用的字符集为"多字节"
程式码 http://codepad.org/aUdBuWV3
今天我想把字符集改为"Unicode"
结果发生了错误
无法将引数char转换为'LPCWSTR'
我Google后发现
LPCWSTR = const wchar_t *
所以做了几点修正
1:char改为wchar_t,双引号前面加L
2:sprintf_s改为swprintf_s
3:strlen()改为wcslen()
4:增加 mysql_options(&myCont, MYSQL_SET_CHARSET_NAME, "utf8");
mysql_set_character_set(&myCont, "utf8");
修改后程式码:http://codepad.org/IhFEG7RM
但是在使用mysql_real_connect()时发生了错误
函式说明:http://i.imgur.com/GY72hjm.jpg
错误图:http://i.imgur.com/LWLkqD1.jpg
请问这样是不是要修改标头档?
(有稍微修改一下 结果问题好像越来越大洞...)
还是有其他方法能在Unicode下使用MySQL API ?
恳请各位前辈赐教
谢谢!
程式码(Code):(请善用置底文网页, 记得排版)
多字节:http://codepad.org/aUdBuWV3
Unicode :http://codepad.org/IhFEG7RM
作者: pttuser (pttuser)   2017-06-17 23:11:00
你应该在unicode用tchar,然后要用char时候只要sprintf到char buffer就好了如果更菜鸟一点,用multibytetowidebyte也可以multibytetowidebyte API应该没拼错吧?很久没写vc了啊应该是widebytetomultibyte啦果然老了,windowsAPI记不住了良好的习惯用tchar不要用wchar or char
作者: LPH66 (-6.2598534e+18f)   2017-06-18 06:33:00
这里其实不是 TCHAR/wchar_t/char 的问题而是 MySQL API 只收 const char * 的关系虽然我没用过, 但根据我在 PHP 的经验, 这个 const char *字串的编码应该是先前 set names 所设定的编码那么当原 PO 手上有的是 wchar_t 时, 就必须要先转码成对应编码的 const char * 字串再送进去如果是 set names utf8; 的话, 用上面推文讲的 windows APIWideCharToMultiByte() 函数就可以转了, 详情可查 MSDN这里反而当使用 TCHAR 会搞乱, 因为如果 TCHAR 是 char 时要先把这个 char* 字串转成 wchar_t* 的 Unicode 字串(使用的是上面那个函式的反向版 MultiByteToWideChar() )再转成 UTF-8 字串才能送进去比 TCHAR 是 wchar_t 时多了一个步骤如果原 PO 没有想要维护两个版本的程式那建议不要 TCHAR而就直接使用 wchar_t 就行了
作者: pttuser (pttuser)   2017-06-18 14:10:00
就说在unicode环境只要把tchar sprintf到char buffer就可以喂给sql api了,widebytetomultibyte也可以啦,不过这种情况用widebytetomultibyte是菜逼巴的人用的楼上那个菜逼巴是听不懂人话喔
作者: firose (guest也是也是也是也是也)   2017-06-18 14:26:00
这么厉害? TCHAR 可以直接 sprintf 到 char buffer ?
作者: pttuser (pttuser)   2017-06-18 16:16:00
废话,windows 环境wide string 可以直接sprintf到char buffer,一堆菜逼巴还在用widebytetomultibyte不过只限ascii code
作者: firose (guest也是也是也是也是也)   2017-06-18 17:12:00
那它还定义 _stprintf 跟 swprintf 干嘛?
作者: LPH66 (-6.2598534e+18f)   2017-06-18 21:03:00
...要不要来做个实验? 就印个 "一" 字就好......等等我看到了你的但书: 只限 ASCII Code = =不过就算这样还是不行的...除非你的 char buffer 别有用途再不然就是你以为是 _UNICODE 其实是 _MBCS所以 TCHAR 还是 char, 那自然可以 sprintf 到 char这似乎也能解释为什么你会有只限 ASCII 的但书在
作者: pttuser (pttuser)   2017-06-19 12:17:00
楼上的菜逼巴,这只是windows的小技巧之一,另外他的charbuffer是要喂给sql api的,又不是要处理拉丁字母,阿拉伯字母,中文等等,另外TCHAR就是widebyte没错,只是format不是%s而是%?自己Google吧看到两个菜逼巴一直在回文,原po对multibyte或是widebyte不熟的话用widebyte <-> multibyte先顶着吧
作者: LPH66 (-6.2598534e+18f)   2017-06-19 14:38:00
不好意思, TCHAR 是 Visual Studio 独有的东西就是为了一支程式能藉给定 _UNICODE 或 _MBCS 编出不同版本所以不会有 printf 的 %? 语法, 只会有 _stprintf 的 %s用 printf 印一个 TCHAR 一定是搞错了什么然后, sql 叙述并不只会有拉丁字母, 指定字段名和给值时都会需要给定实际字串内容, 这正是 MYSQL_SET_CHARSET_NAME的用途; 我不相信一个有一定规模的数据库会没有字串资料甚至在开一个表格时对字串字段都需要给定编码了虽然我只能猜测, 但它 API 设计只吃 char* 的理由很有可能就是为了相容各种编码, 因此只能以最原始的 char*进行传送, 再使用所设定的编码进行解释 / 填入数据库那为了要给定正确的编码给这些字段, 这样子的转码是必须的_s 的函数需要传入目标空间的最大大小, 位置在空间后面所以你需要 swprintf_s(szDir, MAX_PATH, L"%s%s*", ...)关于 wcstombs, 它需要配合 C 语言的 locale 接口来使用问题是 setlocale 的设定方式是跟系统相关的那这样倒不如直接使用所在系统的 API 来做转换以你的状况就是 Windows API

Links booklink

Contact Us: admin [ a t ] ucptt.com