GetCurrentDirectory で取得したディレクトリのひとつ上位にあるディレクトリを取得する方法を教えて下さい。
プロジェクトの場所が
E:\AA\BB\CC\DD\EE.sln
とある場合、GetCurrentDirectory でもとめられるのは
E:\AA\BB\CC\DD だが、
E:\AA\BB\CC までを求めたい。
普通に文字列処理ではダメなのでしょうか?
例えば、
_tsplitpath関数を使って、"E:\AA\BB\CC" を分割する
とか。
その後の処理上、CString 形式ではなく
char Buff[] という形で求めたいので、
#define MAX_PATH 260
char Buff[MAX_PATH], Buff2[MAX_PATH]
GetCurrentDirectory (sizeof(Buff), Buff);
int Code = 0;
for (int i=0; i<MAX_PATH; i++) {
if (Buff[i] == '\\') Code = i;
}
for (i=0; i<Code; i++) {
Buff2[i] = Buff[i];
}
という形で試みてみましたが、Buff2の値が
E:\AA\BB\CCフフフフフフフフフフフフフフフフフフフフフ………
となってしまい、できませんでした。
Buff2のサイズをBuff2[Code]とできればそれでいいのでしょうが、
配列を変数で定義する方法がわからず、
何より、無駄な処理をしているように思えるので質問させていただきました。
まず初期化されていない文字列に対して、
バッファサイズ分の要素を比較しないほうがいいです。
>for (int i=0; i<MAX_PATH; i++) {
でなく
for ( int i = 0; Buff[ i ] != '\0'; i++ )
としましょう。
> for (i=0; i<Code; i++) {
> Buff2[i] = Buff[i];
> }
では、最後の \ の手前までコピーしているだけでなので、
文字列の終端を示す '\0' が入っていません。
Buff2[ Code ] = '\0';
と、ちゃんと入れてあげましょう。
もっとも、文字列の複写ならば、string.hにstrncpyというのがありますので、
strncpy( Buff2, Buff, Code - 1 );
Buff2[ Code ] ='\0';
で同様の処理になります。
ところで、パス文字列には全角文字が含まれるので、'\' の検索では致命的なバグがあります。
Shift_JISでは、1バイトが全角文字を表すコードで2バイト目が '\' のコードという文字が存在します。(ソ とか 能 とかがそう)
'\' 検索時に全角文字を意識して検索しないといけません。
# MFCのCStringのReverseFindメソッドのソースをみると、うまいこと検索しているのが分かります。
こういうめんどくさいことがあったので、最初に
> _tsplitpath関数を使って
といったわけです。
下は _tsplitpath と _tmakepath の例です。
void GetCurrentParentDirectory( LPTSTR lpBuffer )
{
TCHAR szCurrentDirectory[ _MAX_DIR ];
TCHAR szDrive[ _MAX_DRIVE ], szDirectory[ _MAX_DIR ];
GetCurrentDirectory( _MAX_DIR, szCurrentDirectory );
_tsplitpath( szCurrentDirectory, szDrive, szDirectory, NULL, NULL );
_tmakepath( lpBuffer, szDrive, szDirectory, NULL, NULL );
}
int main( void )
{
TCHAR szCurrentParentDir[ _MAX_DIR ];
GetCurrentParentDirectory( szCurrentParentDir );
MessageBox( NULL, szCurrentParentDir, _T( "" ), MB_OK );
return 0;
}
ただ、_tmakepathを使うと、末尾に '\' がつくので注意してください。
余りに初歩的なので回答を躊躇しちゃいますが、今後の「応用」に期待して書きます。
ちなみにVCなら _MAX_PATH は定義済みなのでそれを使う事にします。
もし元のパスも残しておきたいなら・・
char currentPath[_MAX_PATH], parentPath[_MAX_PATH];
GetCurrentDirectory(sizeof(currentPath), currentPath);
strcpy(parentPath, currentPath);
for (size_t p = strlen(parentPath)-1; p >= 0; p--){
if (parentPath[p] == '\\'){
parentPath[p] = 0;
break;
}
}
> 下は _tsplitpath と _tmakepath の例です。
バッファサイズ間違っていました。
_MAX_DIR は ドライブ名 + ':' の文字数を含んでいないですから
_MAX_PATH を指定しないといけなかったです。
> int main( void )
TCHAR 意識するなら
int _tmain( void )
のほうがよかったかな。
解決しました。
今年度プログラミング会社に入社したばかりで初めての仕事だったので、
とても初歩的な質問でしたが、ありがとうございました。
これからの仕事にも応用できると思います。
ツイート | ![]() |