ついに夏本番!さぁ、家族でキャンプに行くぞ! >>

VC++2005のMFCにてプログラムを作成しています。
CFileDialogにてテキストファイルを読み込み、
読込んだファイルパスの「\」を「\\」になるように変換したいのですが、
実装の方法が分かりません。
=====================================
例)C:\test\hoge.txt
⇒ C:\\test\\hoge.txt と変換する。
=====================================
下記にファイルパスをCstring型で読み込み、
char型に変換するまでのプログラムを記載します。
理想としては、char型配列の中に、
「C:\\test\\hoge.txt」のような変換後のファイルパスを
入れたいのです。
解決方法をご存知の方おられましたら、ご教示お願いできませんでしょうか。

【プログラム】
/* ファイルオープンダイアログを表示 */
CFileDialog ReadDlg( TRUE, NULL, "*.txt", OFN_HIDEREADONLY | OFN_FILEMUSTEXIST,
"txtファイル(*.txt)", this );

CStringfilepath;
if( ReadDlg.DoModal() == IDOK )
{
filepath = ReadDlg.GetPathName();// ファイルのフルパス名を取得
}

CFile cfile;
CFileExceptionex;
if( !cfile.Open( filepath, CFile::modeRead , &ex ) )
{
AfxMessageBox( "ファイルを開くのに失敗しました" );// エラーメッセージを表示
return;
}
char st[255] = "";
strcpy( st, filepath );

このQ&Aに関連する最新のQ&A

A 回答 (3件)

>読込んだファイルパスの「\」を「\\」になるように変換したいのですが



単純にReplace()メソッドを呼ぶのでは駄目ですか?

filepath.Replace("\\","\\\\");
    • good
    • 0

MFCなので、単純にCString::Replace()を使えばOKです。



CString s1("c:\\test1\\表1.xls");
s1.Replace("\\", "\\\\");
TRACE ("%s\n", (LPCTSTR)s1);

こんな感じです。
下手に自力でコーディングすると’表'とかの文字で文字化けします。
’表'の1バイト目が'\'と同じコードのため、誤動作します。
(SHIFT-JISの場合)

'\'やフォルダ、ファイル名などを
(日本語Windows系で)扱うとき、
1バイトずつループするのは、
(少なくともCの経験者や専門家の間では)
御法度なので、注意しましょう。

私も、初心者の頃はよくやってしまいました(笑)

MFCであればCStringが吸収してくれるので
(char配列でなく)こちらを採用すべきです。

CStringはLPCSTR等をとる関数には
そのまま(キャストなしで)渡せます。
(暗黙のうちに変換されます)

ただし、printf()等はパラメータのチェックを行わない関数の場合には
明示的にキャストしなければなりません。

なお、関数内で文字列を変更する等の理由で
(LPCTSTRでなく)char*が指定されている場合には
一旦,CString::GetBuffer()でポインタを取り出し、
使用が終わった時点で
CString::ReleaseBuffer()を呼ぶ必要があります。
    • good
    • 0
この回答へのお礼

皆様ご回答ありがとうございます。
検討した結果、上記方法を用いて期待動作することを確認しました。
回答者の皆様ありがとうございました。

お礼日時:2009/05/16 20:33

こんにちは。



力技ですが、こんなコードはどうでしょうか。

void ConvPath(char *r,const char *s)
{
int i,l,p;

p = 0;
l = lstrlen(s);
for(i = 0;i < l;i++){
if(s[i] == '\\'){
r[p++] = '\\';
}
r[p++] = s[i];
r[p] = '\0';
}
}

ConvPath()は、パス文字列の中にある\を\\に変えることが出来る関数です。(今作ったので、動作未確認です;)
rは、変換処理後の文字列を格納する変数です。十分な長さの char* 型を与えてください。
sは、変換処理前の文字列が入った変数です。NULL文字で終端しておいてください。

例:
char before[MAX_PATH],after[MAX_PATH];
lstrcpy(before,"C:\test\hoge.txt");
StrConv(after,before); // これでafterに変換後パスが格納される。
    • good
    • 0

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Qfgetsで拾われる改行文字を削除したい

お世話になります

 C言語初心者のものです。今課題でC言語を用いたプログラミングを
Fedora上でやっています。問題は、fgetsでテキストファイルから、取得
した文字列の中から改行文字を削除できないことです。文字変数のアド
レスはわかっているのですが、終端文字に置換しようとすると、セグメ
ントエラーになってしまいます。これは如何にして解決すべきでしょう
か。よろしくお願いします。

Aベストアンサー

ポインタとかアドレスとか、C言語の用語としてあるものを別の意味に使うとまぎらわしいです。

「ポインタ」「アドレス」と言われたら、 この例なら str, str+i が思い浮びます。
「文字変数のアドレス」だと
char c ;
に対しての
&c
が思い浮びます。

配列なら「添字」、意味的には「x文字目」ですね。

> for(i=0;;i++){
> if(*(str+i)=='/n') {
> *(str+i)='\0';
> break;
> }
> }
/nが\nの間違いなら、この方法で半分正解です。もう少し広い範囲(可能なら全体)で見ないことにはなんとも言えません。
fgetsが最大文字数に達したり、ファイルの最後になったりで、strに改行文字が含まれない場合には、このループは止まりません(Segmentension Falutになって止まる)

・そのような状態になってないか、予めチェックする
・ループを終了させる仕組みを用意しておく
: forの終了条件を記述する、for中で if(*(str+i)=='\0') { break;} 等としておく、等
といった対策が必要です。


あと細かいところを言えば
・strを配列で用意したなら *(s+i)じゃなくてs[i]でいいんじゃないかな
・あるいは char *pみたいにしておいて、 iのループでなく pでループを組む( for(p=str;*p!='\0';p++) )とか。

ポインタとかアドレスとか、C言語の用語としてあるものを別の意味に使うとまぎらわしいです。

「ポインタ」「アドレス」と言われたら、 この例なら str, str+i が思い浮びます。
「文字変数のアドレス」だと
char c ;
に対しての
&c
が思い浮びます。

配列なら「添字」、意味的には「x文字目」ですね。

> for(i=0;;i++){
> if(*(str+i)=='/n') {
> *(str+i)='\0';
> break;
> }
> }
/nが\nの間違いなら、この方法で半分正解です。もう少し広い範囲(可能なら全体)で見ないことにはなんとも言えません。
fgetsが...続きを読む

QGetPrivateProfileStringでiniファイル読込む処理を詳しく知りたいのですが・・・

お世話になっています。

iniファイルを読込み、各変数に代入するC言語のDLLを作成したいのです。
このサイトの投稿や、MSDNなどにも載っていたのですが、
少し理解に苦しみます。

現在まで、理解した点がwindows.hのインクルードを
記述するところ辺りです。
iniファイルは下記のようなレイアウトです。

---<mst.ini>----------------------------
[user]
name=username
ID=userid
[pc]
pcname=FMV
----------------------------------------

#include<windows.h>は記述することまでは
分かりましたが、以下から進みません。。。

GetPrivateProfileString("")

初心者で申し訳ありませんが、お助け願います。

Aベストアンサー

こんにちは。itohhといいます。

サンプルを載せておきます。

mst.iniファイル内の[user]セクションのnameキーの値を取得する。
DWORD dwLen=0;
char strBuf[100];
dwLen = GetPrivateProfileString("user",       // セクション名
                "name",       // キー名
                "soushi_ni",     // デフォルト値
                strBuf,       // 読み込んだ値を格納するエリア
                sizeof(strBuf),   // 上記のエリアのサイズ
                "mst.ini" );     // iniファイル名

解説:
iniファイル名をフルパスで指定しないとWindowsのディレクトリにあるものと判断されます。
Win9xなら「c:\windows」、WinNT系なら「c:\WinNT」。

[user]セクションのnameキーがないときは、デフォルト値で指定した値が設定させます。

復帰値「dwLen」は実際に設定した値(文字列)の長さが返されます。

こんにちは。itohhといいます。

サンプルを載せておきます。

mst.iniファイル内の[user]セクションのnameキーの値を取得する。
DWORD dwLen=0;
char strBuf[100];
dwLen = GetPrivateProfileString("user",       // セクション名
                "name",       // キー名
                "soushi_ni",     // デフォルト値
                strBuf,       // 読み込んだ値を格納するエリア
             ...続きを読む

Qsleep()関数について

"数秒おきに警報をn回鳴らすプログラム"をC言語で作成しようと
考えています。

プログラム実行環境はWindowsですが、
sleep()関数は使用できないのでしょうか??

仮に使用できない場合、この関数に代わる関数や代替方法が
あれば教えて頂けませんでしょうか? 宜しくお願いします。

Aベストアンサー

正確な動作でも構わなければ
windows.hをインクルードして
Sleep()関数を使いましょう.
http://rararahp.cool.ne.jp/cgi-bin/lng/vc/vclng.cgi?print+200207/02070061.txt

しかし,正確に数秒おきに動作を行いたい場合はマルチメディアタイマ等を使いましょう.
マルチメディアタイマはミリ秒間隔でコールバック関数を呼び出すことができます.
timeSetEventを用いてコールバック関数の登録を行うことができます.
timeKillEventでコールバック関数の解除を行うことができます.

多分他にも方法があると思うのですが…私はこれぐらいしか知りません^^;

参考URL:http://www.katto.comm.waseda.ac.jp/~katto/Class/GazoTokuron/code/time.html

Qエディットボックスの入力制限について

いつもお世話になっております。
VS2005でC++を使ってWindowsプログラミングの作成を行っています。

エディットボックスに半角数字のみ入力するような制限はできますが、
この制限をもっと詳しくし、例えば数字の0~60までしか入力できないようにすることは可能でしょうか。

ご教授お願いいたします。

Aベストアンサー

Win32 APIを使っていて、入力があるたびに値のチェックをするのであれば、WM_COMMANDの処理で通知コードがEN_UPDATEまたはEN_CHANGEの場合を扱えば実現できます。
たとえば、エディットボックスのあるダイアログボックスのメッセージハンドラをに以下のような文を挿入すれば、エディットボックスの入力値が変わるごとに入力チェックをしてくれます(半角スペース*2を全角スペースに変換しています)。

case WM_COMMAND:
(挿入ここから)
 if (HIWORD(wParam) == EN_UPDATE/* 表示の変更前にチェックするならEN_CHANGE */ && LOWORD(wParam) == IDC_EDIT/* チェックを行うエディットボックスのコントロールID */)
 {
  char buf[256]; /* 文字列処理用バッファ */
  int value; /* 入力値 */

  GetWindowText((HWND)lParam, buf, 255); /* エディットボックスの文字列取得 */
  value = atoi(buf);
  if (value < 0 || 60 < value) /* 入力値チェック */
  {
   /* 入力値が範囲外であることをユーザーに通知する */
   MessageBox(hDlg, "0から60までの間の数を入力してください。", "入力エラー", MB_OK);
  }
 }
(以下、他のWM_COMMANDメッセージ処理)

ただし、入力値チェックを1からにして動かしてみればわかりますが、入力があるたび値のチェックをすると使う側からすればウザいです。

このような場合、自分ならば、値を入力ではなく選択させる(コンボボックスやスピンコントロールなどを使って)か、入力チェックを入力した値を利用/取得する時点で行うようにします。

Win32 APIを使っていて、入力があるたびに値のチェックをするのであれば、WM_COMMANDの処理で通知コードがEN_UPDATEまたはEN_CHANGEの場合を扱えば実現できます。
たとえば、エディットボックスのあるダイアログボックスのメッセージハンドラをに以下のような文を挿入すれば、エディットボックスの入力値が変わるごとに入力チェックをしてくれます(半角スペース*2を全角スペースに変換しています)。

case WM_COMMAND:
(挿入ここから)
 if (HIWORD(wParam) == EN_UPDATE/* 表示の変更前にチェックするな...続きを読む


人気Q&Aランキング