■概要
C++をVisual Studio2017を使用して開発を行っております。
この度、WritePrivateProfileString関数を使用した際に、対象のファイルの保存形式がS-JISとUTF-16LE(BOM付き)の場合で異なる挙動を示した原因が分からずこの場をお借りして、ご質問させて頂いております。
■iniファイルがSJIS(CRLF)の場合
00 01 02 03 04 05 06 07・・・
5B 00・・・
5b 00 は" [ "を意味しています。UTF16なので、5Bの直後に00が入っています。
■iniファイルがUTF16-LE(BOM付き,CRLF)の場合
00 01 02 03 04 05 06 07・・・
FF FE 0D 00 0A 00 5B 00・・・
最初のFF FEに関してはBOMになります。SJISの方についていないのは当然です。しかし、その直後に0D 0A(おそらく改行コードのCRLF)が入っています。
■デバッグして分かっていること
WritePrivateProfileStringを実施する直前にiniファイルをバイナリで確認したところ、FF FEのBOMを意味する文字コードしか入っていないことを確認済みです。また、WritePrivateProfileString実施直後にiniファイルをバイナリで確認した時に、0D 00 0A 00(改行CRLFを意味する)が入っています。
■まとめ
上記のような差が出る原因がわかりません。私の想いとしては、「iniファイルがUTF16-LE(BOM付き)の場合」であっても、改行コードが入らない状態にすることです。
■iniファイルにCRLFが入るのが嫌な理由
iniファイル作成後、ツールを再起動した際、iniファイルの1行目から読み込み処理を行っていきます。そちらの処理では、1行目に" [ "が存在することが前提として起動する処理であるため、今回の修正で、iniファイルの1行目にFF FE 0D 00 0A 00、つまり" [ "が存在しないのは都合が悪いです。
■コード
①呼び出し側(Dlg.cpp)
ma.CreateIni(b.m_DevName, b.m_SvName, b.m_RcvFolder, b.m_CopyPath, b.m_Port);
②上記①に呼ばれる側(A.cpp)
int A::CreateIni(CString DevName, CString SvName, CString RcvName, CString IniPath, CString Port)
{
if(::WritePrivateProfileString((LPCTSTR)strName, SERVERNAME, (LPCTSTR)SvName, IniPath) == 0)
return -1;
}
③バイナリの書き込み
if (file.Open(strIniPath, CFile::modeWrite | CFile::modeCreate | CFile::shareExclusive)) {
BYTE bom[2] = {0xff, 0xfe};
file.Write(bom, 2);
file.Close();
}
※注
maは「Aクラスのインスタンス」です。
b.xxxは「Bクラスのメンバ変数」で、ダイアログでユーザが入力した値がCString型で格納されています。
回答2件
あなたの回答
tips
プレビュー