プロが教える店舗&オフィスのセキュリティ対策術

VC++6.0でCのコードを書いています。
絶対パスからのファイル名の切り出し方に関して質問です。
FILEPATH="C:\TEST\test.txt"
というファイルがあるとして
"C:\TEST"と"test.txt"の部分を切り離したいと思っています。
フォルダ位置は可変("C:\TEST\TEST"が来ることもある。)
このときに
FILEPATHの先頭アドレスから最後まで
\マークがいくつ来ているか判断して
最後の\マーク以降とそれ以前を
strcpyなどでコピーすればできると思うのですが、
この際、
1.\マークの数を数える
2.最後の\マークの手前までパス名をコピー
3.最後の\マーク以降をファイル名としてコピー
という作業が必要になると思いますが
もっと簡単に行う方法があればお教えいただければと思っています。
(標準関数を使用して・・・など)
よろしくお願いします。

A 回答 (7件)

_splitpath 関数を使用すれば簡単だと思います。


サンプルを示せば、こんな感じです。(見にくいですが)

#include <stdlib.h>
char path[_MAX_PATH]; /* _MAX_PATH260 */
char drive[_MAX_DRIVE]; /* _MAX_DRIVE 3 */
char dir[_MAX_DIR]; /* _MAX_DIR256 */
char name[_MAX_FNAME]; /* _MAX_FNAME256 */
char ext[_MAX_EXT]; /* _MAX_EXT256 */

_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';
    • good
    • 0
この回答へのお礼

お礼が遅れてすみません。遅い時間にも関わらず何度も御回答頂きほんとうにありがとうございました。

お礼日時:2006/04/25 04:28

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標準かどうかが
書かれています。
    • good
    • 1
この回答へのお礼

お礼が遅くなってすみません。\問題の処理への問題喚起、ためになりました。どうもありがとうございました。

お礼日時:2006/04/25 04:32

#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\ピカソ */
    • good
    • 0

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;
}
    • good
    • 0

#2,#3です。


まだ間違いが有りました。本当に申し訳ありません。(寝ぼけて…)

int len;
len = strlen(path);
if (path[len-1] == '\\')path[len-1] = '\0';
    • good
    • 0

#2です。


間違いがありましたので訂正します。すみませんでした。
_makepath(path, drive, dir, NULL, NULL); /* C:\TEST\ */
_makepath(path2, NULL, NULL, name, ext); /* test.txt */
    • good
    • 0

a = strrchr(FILEPATH,'\');


a++;

文字列の最後から検索。
ファイル名の取得
そのファイル名の文字数strlenを数えて
なんだったっけ?
とりあえず部分文字列を出すとか。。。

PathFindFileNameとかいう関数を使うとか?
    • good
    • 0
この回答へのお礼

お礼が遅れてすみません。御回答どうもありがとうございました。

お礼日時:2006/04/25 04:25

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

このQ&Aを見た人はこんなQ&Aも見ています


このQ&Aを見た人がよく見るQ&A