
VC++6.0でCのコードを書いています。
絶対パスからのファイル名の切り出し方に関して質問です。
FILEPATH="C:\TEST\test.txt"
というファイルがあるとして
"C:\TEST"と"test.txt"の部分を切り離したいと思っています。
フォルダ位置は可変("C:\TEST\TEST"が来ることもある。)
このときに
FILEPATHの先頭アドレスから最後まで
\マークがいくつ来ているか判断して
最後の\マーク以降とそれ以前を
strcpyなどでコピーすればできると思うのですが、
この際、
1.\マークの数を数える
2.最後の\マークの手前までパス名をコピー
3.最後の\マーク以降をファイル名としてコピー
という作業が必要になると思いますが
もっと簡単に行う方法があればお教えいただければと思っています。
(標準関数を使用して・・・など)
よろしくお願いします。
No.2ベストアンサー
- 回答日時:
_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';
No.7
- 回答日時:
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標準かどうかが
書かれています。
No.6
- 回答日時:
#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\ピカソ */
No.5
- 回答日時:
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;
}
No.4
- 回答日時:
#2,#3です。
まだ間違いが有りました。本当に申し訳ありません。(寝ぼけて…)
int len;
len = strlen(path);
if (path[len-1] == '\\')path[len-1] = '\0';
No.3
- 回答日時:
#2です。
間違いがありましたので訂正します。すみませんでした。
_makepath(path, drive, dir, NULL, NULL); /* C:\TEST\ */
_makepath(path2, NULL, NULL, name, ext); /* test.txt */
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
このQ&Aを見た人はこんなQ&Aも見ています
-
CStringからchar*への型変換について教えてください。
C言語・C++・C#
-
パスからファイル名を抽出
C言語・C++・C#
-
CStringのFindで文字列検索を行いたいのですが
C言語・C++・C#
-
-
4
CFileDialogの最初のディレクトリ設定
C言語・C++・C#
-
5
ボタンの表示の色、フォントを変更したい
C言語・C++・C#
-
6
ファイル出力の場所を指定
C言語・C++・C#
-
7
ダイアログ内コントロールの位置取得について
C言語・C++・C#
-
8
パスから最後のディレクトリだけを取得したいです
C言語・C++・C#
-
9
DWORDの実際の型は何でしょうか
C言語・C++・C#
-
10
ファイルやディレクトリの存在確認を行う方法
C言語・C++・C#
-
11
CStringの文字列検索&抜き出しについて
C言語・C++・C#
-
12
std::stringからLPCWSTR型への変換
C言語・C++・C#
-
13
VC++で文字列から任意の文字を削除するにはどうしたらいいですか?
C言語・C++・C#
-
14
CString から LPCTSTRの型に変換
C言語・C++・C#
-
15
ダイアログ表示時にチェックボックスにチェックされている状態にするには?
C言語・C++・C#
-
16
VC++にてボタン等のサイズ取得
C言語・C++・C#
-
17
画面を強制的に再描画させる方法
C言語・C++・C#
-
18
ファイルへの書き込み処理について
C言語・C++・C#
-
19
フルパスから最後のディレクトリ名を取得したい。
Visual Basic(VBA)
-
20
ファイルの結合
C言語・C++・C#
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
C言語のfor文です。 繰り返しの...
-
2曲同時再生するにはどうした...
-
ネットワークにつながっている...
-
c言語プログラミング実行時エラ...
-
fgetsなどのときのstdinのバッ...
-
getchar()を int でとる理由...
-
文字列から空白を取り除きたい...
-
3桁区切(コンマ)記号をつけ...
-
簡易grepコマンドの作成を自作...
-
引数の渡し方と受け方(argv)
-
const char** p;のとき、free(p...
-
文字列がNULLか空文字列かの判定
-
文字列中からある文字列とある...
-
C言語 バイナリファイルをfloa...
-
下記のプログラムがコンパイラ...
-
atoi( ) の反対をやりたい
-
str系関数を使わずに二つの文字...
-
テキストデータをそのままバイ...
-
_TCHAR*での引数の読み込み
-
Win32APIでのエディットボック...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
構造体の各メンバにfor文からア...
-
fgetsなどのときのstdinのバッ...
-
文字列から空白を取り除きたい...
-
C言語のfor文です。 繰り返しの...
-
CStringをwchar_tに変換したい
-
間接参照のレベルが異なっています
-
c++ 文字列を入力して、一文字...
-
C言語の入力した文字を反転させ...
-
charからLPTSTRへの変換方法
-
ネットワークにつながっている...
-
'const char *' 型は 'char *' ...
-
テキストデータをそのままバイ...
-
c言語でユーザ関数を利用して入...
-
atoi( ) の反対をやりたい
-
間接操作のレベルとは
-
-'0'の意味について
-
double型の値をchar配列に変換...
-
Linuxでフォルダ内全ファイル名...
-
配列をnビットシフトする
-
型変換
おすすめ情報