2009年12月27日日曜日

フルパスからフォルダ名を取得

 文字列操作とか面倒だなー、何か適当な関数ないかなーと探し回った。

 ざっくりいえばファイルパスをPathRemoveFileSpec()でフォルダパスにして、 PathFindFileName()でフォルダ名だけ取り出せばいける。
これらの関数を使うのに「shlwapi.h」と「shlwapi.lib」のリンクが必要。



以下実験
#include <cstdio>
#include <tchar.h>
#include <windows.h>
#include <shlwapi.h>
#pragma comment(lib, "shlwapi.lib")
 
int main()
{
  TCHAR path[ MAX_PATH ] = {0};
  GetModuleFileName( NULL, path, sizeof(path) );
  _tprintf( TEXT("%s\n"), path ); 
 
  PathRemoveFileSpec( path );
  _tprintf( TEXT("dir: %s\n"), path ); 
  
  _tprintf( TEXT("dirName: %s\n"), PathFindFileName(path) );
 
  return 0;
}

実行結果


D:\develop\study\test_cv2012\Debug\test.exe
dir: D:\develop\study\test_cv2012\Debug
dirName: Debug
続行するには何かキーを押してください . . .


 といった具合。
GetModuleFileNameで自分の実行ファイルパスを取得。
PathRemoveFileSpec()でパスの一番後ろにある「\」以降の文字をバッサリカットしてフォルダパスに。
PathFindFileName()で一番後ろの「\」以降の文字のみを取得でき、これがフォルダ名となる。
 PathRemoveFileSpec()に渡せるパスがファイルかフォルダか不明瞭な場合はPathIsDirectory()でフォルダかどうか確認するのが手っ取り早い。
またフォルダパスの後ろに「\」がついていたりいなかったりする場合が考えられるなら、PathRemoveBackslash()で後ろの「\」をなくせるので利用したい。



以下私事。
PathCombineは"..\\filename.ext"と一個上のフォルダを指定してもちゃんとパスを修正してくれるが、"../filename.ext"とするとうまく動かない。\でないといけないみたい。

 起動時にGetCurrentDirectoryでフォルダパスを保存しておいて、
終了時にそのフォルダパス+ファイル名としてデータを保存していたのだけど、これが大失敗。
 ファイル選択ウィンドウなどでカレントを移動したあと
ShellExecute( NULL, TEXT("open"), execPath, NULL, NULL, SW_SHOWDEFAULT );
などと新しくexecファイルを実行すると、そのexecファイルのカレントフォルダも自身のパスにかかわらず、起動する側のカレントフォルダが反映される。
そのため終了時にデータ保存すると実行ファイルのフォルダとは別の場所に保存される問題が発生した。
 自分のフルパスからフォルダパスを得て、そこにファイル名をくっつけることでこの問題を回避した。
いけてないランチャからプログラムを呼び出された場合似たようなことが起こるかもしれないので、対策しておくといいも知れない。

[参考]
フルパスからフォルダを階層分割するには?
http://rararahp.cool.ne.jp/cgi-bin/lng/vc/vclng.cgi?print+200810/08100010.txt



2013-05-23:
 記事を書き直しました。
フォルダ名とフォルダパスをはき違えていた内容だったので。



0 件のコメント: