INI ファイルから文字列の設定を読み込むための GetPrivateProfileString() という API 関数がありますが、これを普通に使うと陥る罠があります。
GetPrivateProfileString() は、文字列が " か ' で囲まれている場合、それを除去します。
しかし、この動作がまずい結果を生む場合があります。
例えば、INI ファイルに以下のような項目があるとします。
[Settings]
Command="C:\Program Files\Hoge\Hoge.exe" "%1"
これを GetPrivateProfileString() で読み込んだとします。
TCHAR szCommand[MAX_PATH];
GetPrivateProfileString(
TEXT("Settings"), TEXT("Command"), NULL,
szCommand, sizeof(szCommand) / sizeof(TCHAR), szFileName);
すると、読み込まれた文字列は以下のようになってしまいます。
C:\Program Files\Hoge\Hoge.exe" "%1
これでは、この設定を実際に使う時にまずいことになってしまいます。
対策としては、WritePrivateProfileString() で書き出す際に、全体を余分に " で囲っておけば良いでしょう。
例えば C 言語で書くなら以下のようにします。
BOOL WriteIniString(LPCTSTR pszSection, LPCTSTR pszKeyName, LPCTSTR pszString, LPCTSTR pszFileName)
{
if (pszString[0] == _T('"') || pszString[0] == _T('\'')) {
int Length = lstrlen(pszString);
LPTSTR pszBuffer = (LPTSTR)malloc((Length + 3) * sizeof(TCHAR));
BOOL Result;
if (pszBuffer == NULL)
return FALSE;
pszBuffer[0] = _T('"');
lstrcpy(pszBuffer + 1, pszString);
pszBuffer[Length + 1] = _T('"');
pszBuffer[Length + 2] = _T('\0');
Result = WritePrivateProfileString(pszSection, pszKeyName, pszBuffer, pszFileName);
free(pszBuffer);
return Result;
}
return WritePrivateProfileString(pszSection, pszKeyName, pszString, pszFileName);
}
C++ なら std::basic_string
BOOL WriteIniString(LPCTSTR pszSection, LPCTSTR pszKeyName, LPCTSTR pszString, LPCTSTR pszFileName)
{
if (pszString[0] == _T('"') || pszString[0] == _T('\'')) {
std::basic_string<TCHAR> Buffer;
Buffer = _T('"');
Buffer += pszString;
Buffer += _T('"');
return WritePrivateProfileString(pszSection, pszKeyName, Buffer.c_str(), pszFileName);
}
return WritePrivateProfileString(pszSection, pszKeyName, pszString, pszFileName);
}
同様の問題として、文字列の先頭か末尾に空白文字がある場合も、GetPrivateProfileString() で読み込んだ際に除去されてしまいます。
もしそれも維持したい場合は、その判定も加えるといいでしょう。
この問題は、そもそも WritePrivateProfileString() と GetPrivateProfileString() とで対応がとれていないことにあるのですが、限りなくバグに近い仕様ですね。