推 seoker:謝謝你,問題解決了 :D 02/01 19:13
先說我跟windows programming不太熟@@
所以我不知道CA2W跟CW2A是不是是自己會根據傳入資料型態做不同動作。
如果會的話,那底下我說無意義的CA2W/CW2A就變成沒轉換。
字串資料型式分兩種
Byte sequence
Multibyte
char *
CStringA
std::string
在python裡叫str
* 可以是各種編碼,通常是NUL-terminated,但UTF-16/32不是
Word sequence (這邊的word是指一個字)
Widechar
w_char *
CStringW
std::wstring
在python裡叫unicode
* 通常是用整數存Unicode codepoint,int32存就是UCS4,int16存就是UCS2
能不碰CWtring就不要碰,那是給舊程式跳級用的,
現在用的話除非重頭到尾都不需要轉換編碼,不然會有很大的問題,
因為CStringA跟CStringW轉換起來需要的動作根本就不一樣
※ 引述《seoker (Seoker)》之銘言:
: 抱歉,試到現在還是不成功,再上來問一下大家
: 首先,先請各位幫我澄清一下我的觀念有沒有問題:
: 1.
: Unicode 不等於 UTF-8,
: Unicode 用 3 個位元,而 UTF-8 則用 1~4 個位元不等
: 2.
: CString 為中性的,看 Project 的設定,
: 用 Unicode 的話就等同於 CStringW,否則等同 CStringA
: 3.
: MySQL++ 用 std::string,
: 接到的資料是 std::string,query 吃的也是 std::string
: 4.
: std::string 也是 ANSI,可以自由轉換 CStringA 沒問題
: (這裡我比較不清楚..)
: 我在試的時候,以下三行是必加的
: SET NAMES utf8 COLLATE utf8_unicode_ci
: SET CHARACTER_SET_CLIENT=utf8
: SET CHARACTER_SET_RESULTS=utf8
: 我嘗試過:
: (1)
: ( i) std::string => CString
: (ii) CString => CStringA => query
: 以上解決部分,但仍是有字碼無法顯示,或問號
: 好像在第一步轉成 CString 的時候就有問題了
(i)
如果有開Unicode的話
他應該會看你的CP_ACP轉,中文環境的話會資料會被當CP950轉成Unicode
沒開的話
應該就沒轉…bytes抄過去換個資料型態而已
: (2)
: ( i) std::string => MB2WC(CP_ACP、CP_UTF8都試過) => w_char* => CString
: (ii) CString => WC2MB(CP_ACP、CP_UTF8) => char* => CStringA
: 英文字OK,但他國字碼顯示不出、顯示問號,比 (1) 結果還慘
(i)
第一個箭頭跟(1-i)差不多意思,第二個箭頭我不懂你想幹嘛,但先不管你要幹嘛的話:
有開Unicode:
沒轉換
沒開
從Unicode轉回CP_ACP
(ii)
第一個箭頭
有開Unicode
從Unicode轉成你指定CP_ACP/CP_UTF8
沒開
無意義,把char *當int *用
第二個箭頭沒轉換
: (3)
: ( i) std::string => CStringA ==CA2W==> CString
: (ii) CString ==CW2A==> CStringA
: 結果同 (2)
我改了一下你的箭頭,因為你好像把型態跟動作放在等位怕搞混
(i)
第一個箭頭沒轉換
第二個箭頭
有開Unicode
從CP_ACP轉成Unicode
沒開
沒轉換
(ii)
有開Unicode
從Unicode轉成CP_ACP
沒開
無意義
: 更正確的來說,我的字串是用 CMapStringToString 存下來(這應該沒差吧?)
: 我試到快瘋了 O_Q
: 不知道是那邊有問題
: 還是觀念有錯 ..
: 在這邊跟各位請教了 m(_ _)m
不管是怎麼轉,都應該可以一步完成,頂多是資料型態不能直接轉的時候借用中介型態,或是不能直接轉換的時候借用中間編碼。
我不知道CMapStringToString是啥,所以你可以先看看strSQL正不正確,
如果是正確的CP_ACP字串的話,那就要把字串從CP_ACP轉成CP_UTF8
不知道windows有啥工具,iconv可以直接轉。
不能直接轉的話,那就要先從CP_ACP轉成wide string再轉成CP_UTF8。
也就是
CStringA strSQL=...;
CStringW uniSQL=...;
CStringA utfSQL=...;
MultiByteToWideChar(CP_ACP, 0, strSQL, -1, uniSQL, uniSQL的容量)
WideCharToMultiByte(CP_UTF8, 0, uniSQL, -1, utfSQL, utfSQL的容量)
然後把utfSQL送給mysqlpp
當然,SET NAMES UTF8是一定要的。
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 140.131.149.15
※ 編輯: buganini 來自: 140.131.149.15 (02/01 17:13)
※ 編輯: buganini 來自: 140.131.149.15 (02/01 17:14)
※ 編輯: buganini 來自: 140.131.149.15 (02/01 17:23)
※ 編輯: buganini 來自: 140.131.149.15 (02/01 17:39)