ページ 11

ファイルパスからファイル名の取り出し

Posted: 2010年12月04日(土) 22:57
by shiro4ao
ファイルパスからファイル名を取り出したいのですが
実行しても停止してしまいました。
おそらくwhileのループから抜けれていないのかもしれません

ファイルパスはC:\Users\guest\Desktop\sample.txt
なのですが、\が使えないので\\で代用しているのですが
それも原因のようです。
なにか解決方法がありますでしょうか?

コード:

 
#include<stdio.h>
#include<string.h>

void GetFileName(char *buf,char *ret){
	char  *p;
	p=&buf[0];
	while(p!=NULL){
		p=strstr(p,"\\");            //  \が使えない 
		p++;
		printf("%s\n",p);      //確認のためのprintf()
	}
	ret=p;
}


void main()
{
	char file[]="C:\Users\guest\Desktop\sample.txt";
	char ret[1024];
	GetFileName(file,ret);
	printf("ret=%s",ret);

}

Re: ファイルパスからファイル名の取り出し

Posted: 2010年12月04日(土) 23:45
by 七篠
http://e-words.jp/w/E38391E382B9.html

”/”をつかってみては?
MS-DOSなどは”¥”を使っています

Re: ファイルパスからファイル名の取り出し

Posted: 2010年12月04日(土) 23:55
by Justy
まず

コード:

    char file[]="C:\\Users\\guest\\Desktop\\sample.txt";
として下さい。

 あと strstrで NULLが返ってきたとき printfで pを表示するのはまずいです。
 加えて、そのとき p++しているので p==NULLではなくなり、whileを抜けることができません。

Re: ファイルパスからファイル名の取り出し

Posted: 2010年12月05日(日) 00:11
by bitter_fox

コード:


 
#include<stdio.h>
#include<string.h>
 
void GetFileName(char *buf,char *ret){
    char  *p;
    p=&buf[0];


    while(1){ // bitter_fox (1)
        strcpy(ret, p) // bitter_fox (2)

        p=strstr(p,"\\");            //  \が使えない 
        if (p == NULL) // bitter_fox (1')
        {
            break;
        }

        p++;
        printf("%s\n",p);      //確認のためのprintf()
    }
}
 
 
void main()
{
    char file[]="C:\\Users\\guest\\Desktop\\sample.txt"; // ここでも同様に\は使用できない。 bitter_fox (3)
    char ret[1024];
    GetFileName(file,ret);
    printf("ret=%s",ret);
 
}
要点は、ソース内に書きましたが、以下詳しく。

(1) この場合は、(1')でループ脱出を判定するのが正解です。

(2) pに入っていて欲しいのは、\\が無い文字列です。それ(\\が無い文字列)が入っていることを前提に、文字列をコピーします。
入っていない場合
----strstrの戻り値(p)はNULLを指している。よって次に待っているループ脱出(1')でループを脱出して、mainに戻る
入っていた場合
----strstrの戻り値(p)は\\を先頭とした文字列のアドレスを持っている。よって、NULLでは無いのでループを続ける。

(3)文字列に\を使うとエスケープ文字になるので、ここでも同様に\\とする必要があります。

[hr][追記]
boxさん>>strrchr(buf, '\\')
そんな便利な関数があるなんて知らなかった。orz
[hr][修正]
エスケープシーケンス ==> エスケープ文字

Re: ファイルパスからファイル名の取り出し

Posted: 2010年12月05日(日) 00:14
by box

コード:

/*
 * なんちゃってコード
 */
#include <stdio.h>
#include <string.h>

char *GetFileName(char *buf)
{
    return strrchr(buf, '\\') + 1;
}


int main(void)
{
    char file[] = "C:\\Users\\guest\\Desktop\\sample.txt";
    char *ret;

    ret = GetFileName(file);
    if (ret) {
        printf("ret=%s\n", ret);
    }
    return 0;
}

Re: ファイルパスからファイル名の取り出し

Posted: 2010年12月05日(日) 00:47
by shiro4ao
>七篠さん
/を使ったのは何故か/でパスが表示されているからでした。
やはり¥で試してみます。
ありがとうございます。

>Justyさん
インクリメントするタイミングがたしかにおかしかったです
ありがとうございます。

>bitter_foxさん
whileで判定しようとしていたのもまずかったようです
ありがとうございました。

>boxさん
strrchr()という関数があるのですね
勉強になりました
ありがとうございます。



なんとかやってみようと思うので
これで解決にさせていただきたいと思います。
ありがとうございました。

Re: ファイルパスからファイル名の取り出し

Posted: 2010年12月05日(日) 08:08
by box

コード:

/*
 * こっちの方がよかったな…
 */
#include <stdio.h>
#include <string.h>

char *GetFileName(char *buf)
{
    return strrchr(buf, '\\');
}


int main(void)
{
    char file[] = "C:\\Users\\guest\\Desktop\\sample.txt";
    char *ret;

    ret = GetFileName(file);
    if (ret) {
        printf("ret=%s\n", ret + 1);
    }
    return 0;
}

Re: ファイルパスからファイル名の取り出し

Posted: 2010年12月05日(日) 11:11
by へろりくしょん
重隅だとは思いますが、日本語のファイル名は考慮しなくていいのでしょうか。

SJISにおいて、ソ、表、十、禄、等の文字には2バイト目に 0x5C が含まれます。

Re: ファイルパスからファイル名の取り出し

Posted: 2010年12月05日(日) 12:22
by mila
Windows 2000以降の環境であれば、PathFindFileName関数を使うのもいいかもしれません。

コード:

#include <stdio.h>
#include "Shlwapi.h"

#pragma comment(lib, "Shlwapi.lib")
 
int main(void)
{
    const char *path = "C:\\Users\\guest\\Desktop\\sample.txt";
 
    printf("filename=%s\n", PathFindFileName(path));
    return 0;
}

Re: ファイルパスからファイル名の取り出し

Posted: 2010年12月05日(日) 13:35
by dic

コード:

#include<stdio.h>
#include<string.h>
 
void GetFileName(char *buf,char *ret){
    char  *p;
    p=&buf[0];
    while(p!=NULL){
        p=strstr(p,"\\");            //  \が使えない 
		//	p == NULL のときエラー
		if( p )
		{
			printf("%s\n",p);      //確認のためのprintf()
			p++;
		}
    }
    ret=p;	//	ret = 0x0000000 になる
}
 
 
void main()
{
    char file[]="C:\\Users\\guest\\Desktop\\sample.txt";
    char ret[1024];
    GetFileName(file,ret);
    printf("ret=%s",ret);
 
}
気づいた点です
p == NULL のときエラーがでます
ちょっと修正しました
また、main関数内の ret 変数にはなにも代入されないです

Re: ファイルパスからファイル名の取り出し

Posted: 2010年12月05日(日) 15:43
by ISLe
mila さんが書きました:Windows 2000以降の環境であれば、PathFindFileName関数を使うのもいいかもしれません。
CRT関数ですが_splitpathだとWindows95以降に対応します。

コード:

#include <stdio.h>
#include <stdlib.h>
int main(void)
{
	char fname[_MAX_FNAME];
	char ext[_MAX_EXT];
	const char *path = "C:\\Users\\guest\\Desktop\\sample.txt";
	_splitpath(path, NULL, NULL, fname, ext);
	printf("%s%s", fname, ext);
	return 0;
}
VC++以外にBorland C++ Compiler 5.5.1とMinGW32(64)でもコンパイルできました。