ページ 1 / 1
ファイルパスからファイル名の取り出し
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 七篠
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)でもコンパイルできました。