- ベストアンサー
絶対パスからのファイル名の切り離し
VC++6.0でCのコードを書いています。 絶対パスからのファイル名の切り出し方に関して質問です。 FILEPATH="C:\TEST\test.txt" というファイルがあるとして "C:\TEST"と"test.txt"の部分を切り離したいと思っています。 フォルダ位置は可変("C:\TEST\TEST"が来ることもある。) このときに FILEPATHの先頭アドレスから最後まで \マークがいくつ来ているか判断して 最後の\マーク以降とそれ以前を strcpyなどでコピーすればできると思うのですが、 この際、 1.\マークの数を数える 2.最後の\マークの手前までパス名をコピー 3.最後の\マーク以降をファイル名としてコピー という作業が必要になると思いますが もっと簡単に行う方法があればお教えいただければと思っています。 (標準関数を使用して・・・など) よろしくお願いします。
- みんなの回答 (7)
- 専門家の回答
質問者が選んだベストアンサー
- ベストアンサー
_splitpath 関数を使用すれば簡単だと思います。 サンプルを示せば、こんな感じです。(見にくいですが) #include <stdlib.h> char path[_MAX_PATH]; /* _MAX_PATH 260 */ char drive[_MAX_DRIVE]; /* _MAX_DRIVE 3 */ char dir[_MAX_DIR]; /* _MAX_DIR 256 */ char name[_MAX_FNAME]; /* _MAX_FNAME 256 */ char ext[_MAX_EXT]; /* _MAX_EXT 256 */ _splitpath("C:\TEST\test.txt", drive, dir, name, ext); _makepath(path, drive, dir, NULL, ext); /* C:\TEST\ */ _makepath(path2, NULL, NULL, name, NULL); /* test.txt */ C:\TEST\の後ろの\をカットしたい場合は、下記を追加して下さい。 int len; len = strlen(path); if (path[len-1] != '\\') path[len-1] = '\0';
その他の回答 (6)
- sha-girl
- ベストアンサー率52% (430/816)
if (path1[len-1] == '\\')という判定に問題があると思います。 int main(){ int len; char path1[30] = "c:\\aaa\\ピカソ"; len = strlen(path1); if (path1[len-1] == '\\') path1[len-1] = '\0'; printf(path1);//←「c:\aaa\ピカ」になってしまいます。 return 0; } おっしゃる通り_makepathではpathに必ず円マークを返すので 問題無いようでした。すみません。 ただ if (path1[len-1] == '\\') この判定は不要だと思います。 あと_makepathや_spiltpathはCの標準関数ではありません。 当然ですがUNIX系ではコンパイル自体 通らなくなります。 ※MSDNの必要条件の欄に各関数がC標準かどうかが 書かれています。
お礼
お礼が遅くなってすみません。\問題の処理への問題喚起、ためになりました。どうもありがとうございました。
#5さんが指摘されている0x5c(\)問題。 何故か_splitpath関数で問題なく切り出す事が出来ますが…。 strrchr関数による切り出しなら問題が有るのは理解できますが。 問題が有るのなら#2~の回答は取り消して下さい。 このスレッドを汚してしまい、何度もすみません。 【0x5c(\)を含む全角文字列のテスト】 char test1[]="c:\\aaa\\ピカソ"; char test2[]="c:\\aaa\\ピカソ\\能力.txt"; _splitpath(test1, drive, dir, name, ext); _makepath(path1, drive, dir, NULL, NULL); /* c:\\aaa\ */ _makepath(path2, NULL, NULL, name, ext); /* ピカソ */ len = strlen(path1); if (path1[len-1] == '\\') path1[len-1] = '\0'; /* c:\\aaa */ _splitpath(test2, drive, dir, name, ext); _makepath(path1, drive, dir, NULL, NULL); /* c:\aaa\ピカソ\ */ _makepath(path2, NULL, NULL, name, ext); /* 能力.txt */ len = strlen(path1); if (path1[len-1] == '\\') path1[len-1] = '\0'; /* c:\aaa\ピカソ */
- sha-girl
- ベストアンサー率52% (430/816)
SJISコードの場合フォルダ名に 「ソ」や「申」、「十」等の 下位バイトに0x5C(\:円マークと同じコード) が含まれるとそれに反応してしまうので注意してください。 ※例えば「c:\aaa\ピカソ」というパスに対しては #1さんや#2さんのコードでは 意図した結果になりません。 char path[30] = "c:\\aaa\\ピカソ"; char* b = strrchr(path,'\\'); if (b){ *b = '\0'; printf(path); ←「c:\aaa\ピカ」になってしまいます。 } もし扱うコードがSJISでフォルダに全角文字が含まれる可能性があるなら 基本的に前方から検索する必要があります。 #include "stdio.h" #include "string.h" int main() { int i,nlast,nlen; char FILENAME[30]; char FILEPATH[30]="C:\\TEST\\test.txt"; nlen = strlen(FILEPATH); nlast = -1; for( i = 0 ; i < nlen ; i++ ){ if( FILEPATH[i] < 0 ){ i++; continue; } if (FILEPATH[i] == '\\'){ nlast = i; } } if (nlast != -1){ strcpy(FILENAME,FILEPATH+nlast+1); printf("ファイル名=%s\n",FILENAME); *(FILEPATH+nlast) = '\0'; printf("パス=%s\n",FILEPATH); } return 0; }
#2,#3です。 まだ間違いが有りました。本当に申し訳ありません。(寝ぼけて…) int len; len = strlen(path); if (path[len-1] == '\\') path[len-1] = '\0';
#2です。 間違いがありましたので訂正します。すみませんでした。 _makepath(path, drive, dir, NULL, NULL); /* C:\TEST\ */ _makepath(path2, NULL, NULL, name, ext); /* test.txt */
- Missing0001
- ベストアンサー率41% (5/12)
a = strrchr(FILEPATH,'\'); a++; 文字列の最後から検索。 ファイル名の取得 そのファイル名の文字数strlenを数えて なんだったっけ? とりあえず部分文字列を出すとか。。。 PathFindFileNameとかいう関数を使うとか?
お礼
お礼が遅れてすみません。御回答どうもありがとうございました。
お礼
お礼が遅れてすみません。遅い時間にも関わらず何度も御回答頂きほんとうにありがとうございました。