前段時間由於開發一個軟件,需要調用別人的接口,雖然我的軟件是Unicode編碼,對方的模塊也是Unicode編碼,但是對方提供的接口卻是Ansi接口,在非中文系統下,由於涉及到中文路徑,導致Ansi和Unicode編碼轉換出現錯誤,轉換結果不可逆轉。
當OS的區域語言設置為中文時,轉換接口可以逆轉,可以正常使用。
Microsoft提供了GetPrivateProfileStringA、WritePrivateProfileStringA、GetPrivateProfileStringW和WritePrivateProfileStringW用於讀寫INI文件;一下分成四種情況討論字符串內部的轉換邏輯
1)、文件格式為ANSI
a、調用GetPrivateProfileStringA和WritePrivateProfileStringA接口:首先轉換成GetPrivateProfileStringW和WritePrivateProfileStringW接口的調用,中間經過了ANSI字符串到Unicode字符串的轉換(系統完成),然后在寫文件時,又將Unicode字符串轉換成Ansi字符串進行存儲(系統完成),中間經過了兩個不必要的轉換步驟;
b、調用GetPrivateProfileStringW和WritePrivateProfileStringW接口:在寫文件時,將Unicode字符串轉換成Ansi字符串進行存儲(系統完成),中間經過了一個不必要的轉換步驟。
2)、文件格式為Unicode
a、調用GetPrivateProfileStringA和WritePrivateProfileStringA接口:首先轉換成GetPrivateProfileStringW和WritePrivateProfileStringW接口的調用,中間經過了ANSI字符串到Unicode字符串的轉換(系統完成),在寫文件時,不再需要轉換,中間經過了一個個不必要的轉換步驟;
b、調用GetPrivateProfileStringW和WritePrivateProfileStringW接口:由於文件格式和調用的接口都是Unicode格式,所以不存在中間轉換過程,提高了效率。
Unicode格式的INI文件創建
由於系統默認首次創建的文件為ANSI格式,所以需要在使用該文件之前,先用Unicode格式創建好INI文件,這樣在讀寫寫時就是正常的INI文件了。目前我知道創建文件有兩種格式:
1)、向文件中寫入Unicode的文件頭信息,具體文件寫入有
FILE *fp;
fp = _tfopen(_T("e://sss.ini"),_T("r"));
if (fp == NULL)
{
fp=_tfopen(_T("e://sss.ini"), _T("w+b"));
wchar_t m_strUnicode[1];
m_strUnicode[0] = wchar_t(0XFEFF);
fputwc(*m_strUnicode,fp);
}
fclose(fp);
2)、以Unicode格式創建新文件
FILE *pFile(NULL);
if((nRet= _wfopen_s(&pFile, m_wszConfigFile, L"wt, ccs=UNICODE")) == 0)
fclose(pFile);
或者
if((nRet= _wfopen_s(&pFile, m_wszConfigFile, L"wt, ccs=UTF-16LE")) == 0)
fclose(pFile);
經測試,windows下默認編碼950,ccs=UTF-16LE創建的unicode格式文件可以正確寫入寬字符。
注意:調用讀寫INI文件的接口其實最后都是Unicode接口,具體寫入到文件中的內容是由文件的格式決定,並非調用的接口決定。