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

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
アバター
shiro4ao
記事: 224
登録日時: 9年前
住所: 広島

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

#1

投稿記事 by shiro4ao » 9年前

ファイルパスからファイル名を取り出したいのですが
実行しても停止してしまいました。
おそらく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);

}

七篠
記事: 8
登録日時: 9年前

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

#2

投稿記事 by 七篠 » 9年前

http://e-words.jp/w/E38391E382B9.html

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

アバター
Justy
副管理人
記事: 122
登録日時: 9年前
住所: 神奈川県

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

#3

投稿記事 by Justy » 9年前

まず

コード:

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

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

アバター
bitter_fox
記事: 607
登録日時: 9年前
住所: 大阪府

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

#4

投稿記事 by bitter_fox » 9年前

コード:


 
#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][修正]
エスケープシーケンス ==> エスケープ文字
最後に編集したユーザー bitter_fox on 2010年12月05日(日) 00:44 [ 編集 2 回目 ]

box
記事: 1747
登録日時: 9年前

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

#5

投稿記事 by box » 9年前

コード:

/*
 * なんちゃってコード
 */
#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;
}
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

アバター
shiro4ao
記事: 224
登録日時: 9年前
住所: 広島

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

#6

投稿記事 by shiro4ao » 9年前

>七篠さん
/を使ったのは何故か/でパスが表示されているからでした。
やはり¥で試してみます。
ありがとうございます。

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

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

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



なんとかやってみようと思うので
これで解決にさせていただきたいと思います。
ありがとうございました。
最後に編集したユーザー shiro4ao on 2010年12月06日(月) 15:42 [ 編集 1 回目 ]

box
記事: 1747
登録日時: 9年前

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

#7

投稿記事 by box » 9年前

コード:

/*
 * こっちの方がよかったな…
 */
#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;
}
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

アバター
へろりくしょん
記事: 92
登録日時: 9年前
住所: 福岡

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

#8

投稿記事 by へろりくしょん » 9年前

重隅だとは思いますが、日本語のファイル名は考慮しなくていいのでしょうか。

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

mila

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

#9

投稿記事 by mila » 9年前

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;
}

dic
記事: 582
登録日時: 9年前
住所: 宮崎県

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

#10

投稿記事 by dic » 9年前

コード:

#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 変数にはなにも代入されないです
添付ファイル
無題.JPG

ISLe
記事: 2648
登録日時: 9年前
連絡を取る:

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

#11

投稿記事 by ISLe » 9年前

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)でもコンパイルできました。

閉鎖

“C言語何でも質問掲示板” へ戻る