変数に格納された\を\\にするには?

解決


\を\\にしたい人  2005-10-17 16:39:16  No: 59285  IP: 192.*.*.*

m_FileSection.GetWindowText(csFilePath);
上記のcsFilePathには
"C:\Program Files\Microsoft Office\CLIPART\PUB60COR\HTECH_01.MID"
という、\が入った変数があります。
この変数には\が入っているのですが、
WritePrivateProfileString(csIniTitle,csIniSec,csSec,csIniFileName);
と、iniファイルに書き込もうとするとエラーになってしまいます。
\が”、\\が\と認識されるからだそうです。
どうすれば変数の中の\を\\にできるか教えて下さい。

編集 削除
\を\\にしたい人  2005-10-17 16:42:04  No: 59286  IP: 192.*.*.*

追記事項です。
GetWindowTextで読み取る値は変更できないとします。

編集 削除
Blue  2005-10-17 16:44:00  No: 59287  IP: 192.*.*.*

> \が”、\\が\と認識されるからだそうです。
この情報はどこから取得しましたか?

> WritePrivateProfileString(csIniTitle,csIniSec,csSec,csIniFileName);

csFilePathはないようですが?

すこし情報が足りないようです。
 使用OS          (例:WindowsXP Pro SP2)
 使用コンパイラ    (例:Visual C++ 6.0 Enter SP6)
 プロジェクトの種類 (例:MFC Application SDI)

を明記してください。

編集 削除
Blue  2005-10-17 16:46:36  No: 59288  IP: 192.*.*.*

> m_FileSection.GetWindowText
からMFCっぽいですね。

単に置換をしたいならば、CStringにReplaceメソッドってのがあります。

編集 削除
\を\\にしたい人  2005-10-17 17:12:17  No: 59289  IP: 192.*.*.*

\が”、\\が\と調べたのはヘルプでキーワードで[\\]と検索して調べました。
今さらですが、環境は明記されたのと同じ、
 使用OS          (WindowsXP Pro SP2)
 使用コンパイラ    (Visual C++ 6.0 Enter SP6)
 プロジェクトの種類 (MFC Application SDI)
です。
WritePrivateProfileString
(csIniTitle,csIniSec,csSec,csIniFileName);
ではなく、
WritePrivateProfileString(csIniTitle,csIniFilePath,csFilePath,csIniFileName);
でした。訂正します。

只今、再コーディング中ですので、解決しましたら追って報告します。

編集 削除
みい  2005-10-17 17:16:01  No: 59290  IP: 192.*.*.*

私はVC6(SP5)MFCでエディット内のフォルダパスをそのまま
WritePrivateProfileStringでINIファイルに書き込んでますが、
正常に書き込めています。

INIファイルのパスのフォルダがないとか?

編集 削除
Blue  2005-10-17 17:32:13  No: 59291  IP: 192.*.*.*

> と、iniファイルに書き込もうとするとエラーになってしまいます。
エラーは実行時エラーなんですよね?
エラーの内容をまるまる提示してもらえませんでしょうか?

他のところで、排他でINIファイルを開いているとかしてはいませんよね?

編集 削除
\を\\にしたい人  2005-10-17 17:37:11  No: 59292  IP: 192.*.*.*

>みいさん
フォルダは実在します。

>Blueさん
> と、iniファイルに書き込もうとするとエラーになってしまいます。
上記の文ですが、コンパイルも実行も通ります。
しかし、バージョンの低い6.0ではエラーは出ません。
新しいVC++.NETの環境で同じことをしたらエラーが出てきましたので気づきました。尚、他のところで排他でINIファイルは開いていません。

編集 削除
Blue  2005-10-17 17:45:23  No: 59293  IP: 192.*.*.*

> 新しいVC++.NETの環境で同じことをしたらエラーが出てきましたので気づ
> きました。尚、他のところで排他でINIファイルは開いていません。
私は.NETを持っていないので確かめようがないですが、
\を含む文字列だけNGなのでしょうか?そのほかの文字はOK?

> \が”、\\が\と調べたのはヘルプでキーワードで[\\]と検索して調べました。
このようなことは聞いたことがないのですが、MSDNのヘルプでしょうか?
(NETから仕様がかわった?)
# \" が " \\ が \ というのは知っていますが。
http://www.microsoft.com/japan/developer/library/vccore/_langref_escape_sequences.htm

編集 削除
\を\\にしたい人  2005-10-17 17:55:18  No: 59294  IP: 192.*.*.*

その他の文字は大丈夫でした。
ヘルプはMSDNです。

先ほどのCString::Replace(chOld,chNew,lpszOld,pszNew)の
関数を使って置換を使用としましたが、chOld,chNewを"\","\\"と入力したら
「不要な箇所に、エスケ-プシ-ケンスが付いています。」
とエラーが出てしまいました。どうしたらいいでしょうか?

編集 削除
シャノン  2005-10-17 17:58:56  No: 59295  IP: 192.*.*.*

GetWindowText や WritePrivateProfileString を呼び出している関数のコードを全部載せたほうが手っ取り早いと思います。

編集 削除
Blue  2005-10-17 18:00:43  No: 59296  IP: 192.*.*.*

まず、文字列で\を表すには、
"\\"
としないといけません。
よって
CString s = "\";
とすると
"のエスケープとして解釈し、リテラルが閉じていない状態になります。

> ヘルプはMSDNです。
http://www.microsoft.com/japan/developer/library/vccore/_langref_escape_sequences.htm
とは違う内容でしょうか?
その内容を抜粋して載せてくれませんでしょうか?

編集 削除
\を\\にしたい人  2005-10-17 18:14:20  No: 59297  IP: 192.*.*.*

ヘルプはここで見ました。
http://www.microsoft.com/japan/developer/library/vclang/_clang_parsing_c_command.2d.line_arguments.htm

もっと詳しく調べていきましたら、三文字表記できる事がわかりました。ここでは"??/"が"\"(これの半角)で記載されています。\という意味みたいです。 
http://www.microsoft.com/japan/developer/library/vclang/_clang_trigraphs.htm

しかし、
csFilePath.Replace(??/,??/??/);
や、
csFilePath.Replace(??/,"\\");
と書いてもエラーがでます。
以上です。よろしくお願いします。

編集 削除
\を\\にしたい人  2005-10-17 18:25:01  No: 59298  IP: 192.*.*.*

わかりました。
"\"を"と認識してしまうのであれば、
csFilePath.Replace("\\","\\\\");
と書けばいいようです。お手数おかけしました。

以上です。

編集 削除
\を\\にしたい人  2005-10-17 18:25:58  No: 59299  IP: 192.*.*.*

解決しました。

編集 削除
Blue  2005-10-17 20:04:20  No: 59300  IP: 192.*.*.*

> \を\\にしたい
は解決したかもしれませんが、
結局のところINIファイルにはちゃんと自分の思っていたとおりの文字が書き込まれたのでしょうか?

http://www.microsoft.com/japan/developer/library/vclang/_clang_parsing_c_command.2d.line_arguments.htm
ここのヘルプってコマンドラインだから、INIファイルの出力に関係ないと思うんだけど。。。

編集 削除
みい  2005-10-17 20:14:22  No: 59301  IP: 192.*.*.*

> しかし、バージョンの低い6.0ではエラーは出ません。
> 新しいVC++.NETの環境で同じことをしたらエラーが出てきましたので気づきました。尚、他のところで排他でINIファイルは開いていません。

ちょっと気になったので、VC++.NET(2003)でテスト。
エディットとボタン貼り付けて、ボタン押しでWritePrivateProfileStringするようにしました。
エディットに
C:\Program Files\Microsoft Office\CLIPART\PUB60COR\HTECH_01.MID
を入力してボタン押し。
…エラー出ません。ファイルにも書き込めてます。

編集 削除
RAPT  2005-10-17 21:28:36  No: 59302  IP: 192.*.*.*

> 三文字表記できる事がわかりました。ここでは"??/"が"\"(これの半角)
いや、だから、バックスラッシュは、円記号と同じ文字です。
"\"にみえるか"¥"に見えるかは環境依存です。

> しかし、
> csFilePath.Replace(??/,??/??/);
> や、
> csFilePath.Replace(??/,"\\");
csFilePath.Replace(\,\\);
csFilePath.Replace(\,"\\");
としているのと等価なので、当然ながらコンパイルエラーとなります。
# 文字リテラルは クォーテーションで括りましょう。

編集 削除
\を\\にしたい人  2005-10-18 11:13:45  No: 59303  IP: 192.*.*.*

>Buleさん
確かに思った通りには書き込まれませんでした。
そもそもコーディングの仕方が甘かったようです。
後でいろいろ悩んだ結果、以下の様に書くと書き込める事が判明しました。

char buff[1024];
DWORD dwLen = GetModuleFileName(NULL, buff, sizeof(buff));
CString csModulePath(buff);
int iPos = csModulePath.ReverseFind('\\');
CString csModuleDir   = csModulePath.Left(iPos);
CString csIniFileName = csModuleDir + "\\Alarm.ini";
CString csIniTitle    ="AlarmData";
CString csIniFilePathName ="FilePath";  
WritePrivateProfileString(csIniTitle,csIniFilePathName,CPathName,csIniFileName);

と書き込むと、iniファイルに出力されます。
ソースに直接書くときは\\を二つ書かなくてはいけない。
iniファイルに書き込む、読み込む時には\がひとつのままでいい。

この事を知ったので、\\に対する問題はなくなりました。
協力して頂いた皆さん。ありがとうございました。

編集 削除
Blue  2005-10-18 11:19:04  No: 59304  IP: 192.*.*.*

ちなみにパスを分解するときは、_splitpath関数
パスをくっつけるときは、_makepath関数を使ったほうが確実です。
(CStringのReverseFindならばOKだと思いますけど。)
# Path〜というAPIもありますけどね。

編集 削除
\を\\にしたい人  2005-10-18 11:22:53  No: 59305  IP: 192.*.*.*

以後、Blueさんのアドバイスを元にコーディングしていきたいと思います。
多くのアドバイスありがとうございました。

編集 削除
RAPT  2005-10-18 21:40:36  No: 59306  IP: 192.*.*.*

シェルAPIの使用例です。

#include <shlwapi.h>
#pragma comment(lib, "shlwapi.lib")

TCHAR sz[MAX_PATH] = {0};
GetModuleFileName(NULL, sz, sizeof sz);
// (C:\CppProject\cpptest\Debug\cpptest.exe)

::PathRemoveFileSpec(sz);
::PathAppend(sz, _T("Alarm.ini"));
// (C:\CppProject\cpptest\Debug\Alarm.ini)

編集 削除