パス文字列の操作
ファイルやディレクトリなどの場所を示す文字列をパスと言います。
ここではパス文字列を操作・加工する関数を一部紹介します。
PathCch系関数とPath系関数
パス操作関数には主に「PathCch○○」の形式と「Path○○」の形式があります。
PathCch系の関数はWindows8以降で使用可能です。
Windows7以前の環境に対応する場合はPath系関数を使用する必要があります。
Path系関数はバッファのサイズを指定する引数がなく、バッファオーバーランの危険性があるので、可能ならPathCch系を使用します。
(ただし全てのPath系関数に対応するPathCch版があるわけではありません)
PathCch系の関数の使用にはPathcch.lib
のリンクおよびPathcch.h
のインクルードが必要です。
#pragma comment(lib, "Pathcch.lib")
#include <windows.h>
#include <Pathcch.h>
PathCch系関数では、文字列の「サイズ」「長さ」は文字数を意味します。
全てWCHAR型文字列用で、char型文字列用はありません。
戻り値がHRESULT型の場合、関数の成功/失敗を示す定数が返されます。
SUCCEEDED
マクロまたはFAILED
マクロで成否を判別します。
WCHAR path[MAX_PATH] = L"C:\\test";
HRESULT result = PathCchAddBackslash(path, MAX_PATH);
if(SUCCEEDED(result)) {
//成功
}
else
{
//失敗
}S
Path系の関数の使用にはShlwapi.lib
のリンクおよびShlwapi.h
のインクルードが必要です。
#pragma comment(lib, "Shlwapi.lib")
#include <windows.h>
#include <Shlwapi.h>
Path系の関数を使用する場合はコピー先となる文字列バッファのサイズは十分な大きさを取るようにしてください。
(MAX_PATH
が望ましいが、それでも完全には防げない)
元のパス文字列よりも長くなる可能性のある加工を行うPath系関数は、バッファオーバーランの危険性が特に高いため標準で無効になっています。
使用する場合はコードの先頭に以下の一行を追加します。
#pragma warning(disable : 4995)
なお、ここで紹介する関数はすべて指定のパスにファイルやディレクトリが存在するか否かは動作に関係しない、単純な文字列操作関数です。
例えばPathFileExists関数などは実際のファイルの有無により動作が変わりますが、そういった関数はこのページでは紹介しません。
また、実際のファイルが操作されることはありません。
目次
- パスに使用可能な文字のチェック
- 末尾に区切り文字を追加
- 末尾の区切り文字を除去
- 拡張子の追加
- 拡張子の削除
- 拡張子の変更
- 拡張子の検索
- ファイル名の検索
- 区切り文字の検索
- 末尾文字列の検索
- 先頭文字列のチェック
- ドライブ名のチェック
- ファイル名か否かのチェック
- ルートディレクトリのチェック
- 共通のルートをチェック
- 共通の接頭辞の検索
- ワイルドカードのテスト
- ルートの除去
- ディレクトリの除去
- ルートディレクトリの取得
- 末尾要素の除去
- パスの正規化
- 相対パスのチェック
- 相対パスの取得
- URL形式のチェック
- パスの結合
パスに使用可能な文字のチェック
PathGetCharType関数
PathGetCharType
関数は、文字がパス文字として使用可能かをチェックします。
- UINT PathGetCharTypeW(
WCHAR ch
); - 文字chがパスに使用可能かを判定する。
戻り値は以下の定数の組み合わせです。
定数 | 説明 |
---|---|
GCT_INVALID (0) |
パスとして無効な文字 |
GCT_LFNCHAR (1) |
長いファイル名で有効な文字 |
GCT_SHORTCHAR (2) |
短いファイル名(8.3形式)で有効な文字 |
GCT_WILD (4) |
ワイルドカード文字 |
GCT_SEPARATOR (8) |
区切り文字 |
例えばアルファベットは長いファイル名にも短いファイル名にも使用できるので、GCT_LFNCHAR
とGCT_SHORTCHAR
の組み合わせが返ります。
ワイルドカード文字は「?」と「*」で、通常のパス文字列には使用できず、プログラム上で使用される文字です。
この関数は「文字」ひとつをチェックする関数です。
文字列全体が有効なパス文字列かをチェックするものではないので注意してください。
末尾に区切り文字を追加
PathCchAddBackslash関数
PathCchAddBackslash
関数は、パス文字列の末尾にパス区切り文字(\記号)を追加します。
- WINPATHCCHAPI HRESULT PathCchAddBackslash(
PWSTR pszPath,
size_t cchPath
); - 長さcchPathのパス文字列pszPathの末尾にパス区切り文字を追加する。
成功した場合はS_OKを返す。
末尾が既に区切り文字である場合はS_FALSEを返す。
失敗した場合はそれ以外の値を返す。
この関数は文字列の末尾が既に区切り文字である場合は何もしません。
PathCchAddBackslashEx関数
PathCchAddBackslashEx
関数は基本的にPathCchAddBackslash関数と同じですが、関数成功時に文字列バッファの残りの領域に関する情報を得ることができます。
- WINPATHCCHAPI HRESULT PathCchAddBackslashEx(
PWSTR pszPath,
size_t cchPath,
PWSTR *ppszEnd,
size_t *pcchRemaining
); - 長さcchPathのパス文字列pszPathの末尾にパス区切り文字を追加する。
文字ポインタppszEndには終端のNULL文字へのポインタが格納される。
サイズポインタpcchRemainingにはpszPathの残りのサイズが格納される。
成功した場合はS_OKを返す。
末尾が既に区切り文字である場合はS_FALSEを返す。
失敗した場合はそれ以外の値を返す。
第三引数ppszEnd
は文字列型のポインタを指定します。
(要するにWCHAR*型のポインタ渡し)
関数成功時、ここには終端のNULL文字の位置が格納されます。
第四引数pcchRemaining
はsize_t型のポインタを指定します。
関数成功時、ここには終端のNULL文字以降の余った文字列の数が格納されます。
(NULL文字を含む)
PathAddBackslash関数
PathAddBackslash
関数は、パス文字列の末尾にパス区切り文字(\記号)を追加します。
- LPWSTR PathAddBackslashW(
LPWSTR pszPath
); - パス文字列pszPathの末尾にパス区切り文字を追加する。
戻り値は終端のNULL文字へのポインタ。
失敗した場合はNULL。
この関数は文字列の末尾が既に区切り文字である場合は何もしません。
末尾の区切り文字を除去
PathCchRemoveBackslash
PathCchRemoveBackslash
関数は、パス文字列の末尾の区切り文字を除去します。
- WINPATHCCHAPI HRESULT PathCchRemoveBackslash(
PWSTR pszPath,
size_t cchPath
); - 長さcchPathのパス文字列pszPathから、末尾のパス区切り文字を除去する。
成功した場合はS_OKを返す。
末尾が区切り文字でない場合はS_FALSEを返す。
失敗した場合はそれ以外の値を返す。
PathCchAddBackslash関数の逆の働きをする関数です。
PathCchRemoveBackslashEx関数
PathCchRemoveBackslashEx
関数は基本的にPathCchRemoveBackslash関数と同じですが、関数成功時に文字列バッファの残りの領域に関する情報を得ることができます。
(→PathCchAddBackslashEx関数)
- WINPATHCCHAPI HRESULT PathCchRemoveBackslashEx(
PWSTR pszPath,
size_t cchPath,
PWSTR *ppszEnd,
size_t *pcchRemaining
); - 長さcchPathのパス文字列pszPathから、末尾のパス区切り文字を除去する。
文字ポインタppszEndには終端のNULL文字へのポインタが格納される。
サイズポインタpcchRemainingにはpszPathの残りのサイズが格納される。
成功した場合はS_OKを返す。
末尾が既に区切り文字である場合はS_FALSEを返す。
失敗した場合はそれ以外の値を返す。
PathRemoveBackslash関数
PathRemoveBackslash
関数は、パス文字列の末尾の区切り文字を除去します。
- LPWSTR PathRemoveBackslashW(
LPWSTR pszPath
); - パス文字列pszPathから、末尾のパス区切り文字を除去する。
拡張子の追加
PathCchAddExtension関数
PathCchAddExtension
関数は、パス文字列の末尾に拡張子を追加します。
- WINPATHCCHAPI HRESULT PathCchAddExtension(
PWSTR pszPath,
size_t cchPath,
PCWSTR pszExt
); - 長さcchPathのパス文字列pszPathの末尾に拡張子文字列pszExtを追加する。
成功した場合はS_OKを返す。
文字列pszPathに既に拡張子がある場合はS_FALSEを返す。
戻り値は以下の定数のいずれかです。
定数 | 説明 |
---|---|
S_OK | 関数の成功。 |
S_FALSE | パス文字列にはすでに拡張子がある。 |
PATHCCH_E_FILENAME_TOO_LONG | バッファサイズが足りないため追加できなかった。 |
E_INVALIDARG | その他のエラー。 |
パス文字列にすでに拡張子がある場合は文字列は変更されません。
第三引数pszExt
は拡張子を示す文字列ですが、ピリオドの有無はどちらでも構いません。
つまり「.txt」でも「txt」でも同じ動作になります。
ピリオドのみを指定した場合はS_OKを返し、元の文字列は変更されません。
拡張子を操作する関数全般に言えることですが、ドット(ピリオド)を含むファイル名の場合は意図した通りの動作にはなりません。
PathAddExtension関数
PathAddExtension
関数は、パス文字列の末尾に拡張子を追加します。
- BOOL PathAddExtensionW(
LPWSTR pszPath,
LPCWSTR pszExt
); - パス文字列pszPathの末尾に拡張子文字列pszExtを追加する。
成功した場合はTRUEを、失敗した場合はFALSEを返す。
パス文字列にすでに拡張子がある場合は文字列は変更されません。
第一引数pszPath
にNULL
を指定すると結果は拡張子のみの文字列となります。
第二引数pszExt
にNULL
を指定すると拡張子「.exe」が追加されます。
拡張子の削除
PathCchRemoveExtension関数
PathCchRemoveExtension
関数は、パス文字列から拡張子を削除します。
- WINPATHCCHAPI HRESULT PathCchRemoveExtension(
PWSTR pszPath,
size_t cchPath
); - 長さcchPathのパス文字列pszPathから拡張子を削除する。
成功した場合はS_OKを返す。
拡張子が無い場合はS_FALSEを返す。
失敗した場合はそれ以外の値を返す。
PathRemoveExtension関数
PathRemoveExtension
関数は、パス文字列から拡張子を削除します。
- void PathRemoveExtensionW(
LPWSTR pszPath
); - パス文字列pszPathから拡張子を削除する。
戻り値はなし。
拡張子の変更
PathCchRenameExtension関数
PathCchRenameExtension
関数は、パス文字列の拡張子を置き換えます。
- WINPATHCCHAPI HRESULT PathCchRenameExtension(
pszPath,
size_t cchPath,
PCWSTR pszExt
); - 長さcchPathのパス文字列pszPathの拡張子を文字列pszExtに置き換える。
文字列pszPathに拡張子が存在しない場合は追加する。
成功した場合はS_OKを返す。
失敗した場合はそれ以外の値を返す。
第三引数pszExt
は拡張子を示す文字列ですが、ピリオドの有無はどちらでも構いません。
つまり「.txt」でも「txt」でも同じ動作になります。
パス文字列に拡張子がない場合は追加します。
拡張子に空の文字列を指定するとパス文字列から拡張子を削除します。
PathRenameExtension関数
PathRenameExtension
関数は、パス文字列の拡張子を置き換えます。
- BOOL PathRenameExtensionW(
LPWSTR pszPath,
LPCWSTR pszExt
); - パス文字列pszPathの拡張子を文字列pszExtに置き換える。
成功した場合はTRUEを、失敗した場合はFALSEを返す。
拡張子の検索
PathCchFindExtension関数
PathCchFindExtension
関数は、パス文字列から拡張子を検索します。
- WINPATHCCHAPI HRESULT PathCchFindExtension(
PCWSTR pszPath,
size_t cchPath,
PCWSTR *ppszExt
); - 長さcchPathのパス文字列pszPathから拡張子のピリオドの位置へのポインタを取得し、文字ポインタ変数ppszExtに格納する。
成功した場合はS_OKを返す。
失敗した場合はそれ以外の値を返す。
PathFindExtension関数
PathFindExtension
関数は、パス文字列から拡張子を検索し位置を返します。
- LPCWSTR PathFindExtensionW(
LPCWSTR pszPath
); - パス文字列pszPathから拡張子のピリオドの位置へのポインタを返す。
見つからなかった場合はNULLを返す。
ファイル名の検索
PathFindFileName関数
PathFindFileName
関数は、パス文字列からファイル名の位置を返します。
- LPCWSTR PathFindFileNameW(
LPCWSTR pszPath
); - パス文字列pszPathからファイル名の位置へのポインタを返す。
見つからなかった場合はパス文字列先頭へのポインタを返す。
「ファイル名」はパス文字列中の最後の区切り文字以降の文字列です。
ただし文字列の末尾が区切り文字の場合は最後から二番目の区切り文字以降をファイル名とみなします。
ルートディレクトリ名のみを指定した場合はパス文字列の先頭位置を返します。
WCHAR* p;
WCHAR* path = L"C:\\test\\abc.txt";
p = PathFindFileName(path);
//abc.txt
path = L"C:\\test\\abc.txt\\";
p = PathFindFileName(path);
//abc.txt\
path = L"C:\\";
p = PathFindFileName(path);
//C:\
バッファ文字列自体を加工したい場合はPathStripPath関数を使用します。
区切り文字の検索
PathFindNextComponent関数
PathFindNextComponent
関数は、パス文字列から区切り文字を検索し、その次の文字の位置を返します。
- LPCWSTR PathFindNextComponentW(
LPCWSTR pszPath
); - パス文字列pszPathから区切り文字(\記号)の次の文字へのポインタを返す。
見つからなかった場合はパス文字列の終端NULL文字へのポインタを返す。
パス文字列pszPathがNULL文字の場合、および関数が失敗した場合はNULLを返す。
この関数は文字列中の最初の区切り文字の次の文字へのポインタを返します。
終端のNULL文字が現れるまで繰り返すことで、パス文字列中のディレクトリ名とファイル名をすべて取得することができます。
末尾文字列の検索
PathFindSuffixArray関数
PathFindSuffixArray
関数は、パス文字列の末尾が文字列配列中のいずれかの文字列と一致するかを検索し、その位置を返します。
- LPCWSTR PathFindSuffixArrayW(
LPCWSTR pszPath,
const LPCWSTR *apszSuffix,
int iArraySize
); - パス文字列pszPathが、要素数iArraySizeの文字列配列apszSuffix内のいずれかの文字列で終了するかを検索する。
成功した場合は見つかった文字列へのポインタを返す。
失敗した場合はNULLを返す。
関数の呼び出しの前に、末尾文字列リストを格納する配列を用意しておきます。
文字列は大文字と小文字を区別します。
WCHAR *path = L"C:\\test\\abc.txt";
WCHAR *suffixs[] = {
L".exe", L".txt", L".jpg"
};
int suffixsLen = sizeof(suffixs) / sizeof(suffixs[0]);
WCHAR *suffix = PathFindSuffixArray(path, suffixs, suffixsLen);
//ポインタsuffixはpath中の「.txt」の位置を指す
先頭文字列のチェック
PathIsPrefix関数
PathIsPrefix
関数は、パス文字列が指定の文字列から始まるか否かを判定します。
- BOOL PathIsPrefixW(
LPCWSTR pszPrefix,
LPCWSTR pszPath
); - パス文字列pszPathが文字列pszPrefixで始まる場合はTRUEを返す。
それ以外の場合はFALSEを返す。
ドライブ名のチェック
PathGetDriveNumber関数
PathGetDriveNumber
関数は、パス文字列が有効なドライブ文字列から始まるか否かを判定します。
- int PathGetDriveNumberW(
LPCWSTR pszPath
); - パス文字列pszPathが「A:」から「Z:」の範囲の文字列から始まる場合は対応するドライブ番号を返す。
それ以外の場合は-1を返す。
ドライブ文字列は「A:」から「Z:」の範囲で、0から25の範囲の数値が返されます。
大文字小文字は区別されません。
コロン以降の文字列は無視されます。
あくまでもパス文字列のチェックで、システムにそのドライブが存在しなくても動作は変わりません。
ファイル名か否かのチェック
PathIsFileSpec関数
PathIsFileSpec
関数は、パス文字列がファイル名か否かを判定します。
- BOOL PathIsFileSpecW(
LPCWSTR pszPath
); - パス文字列pszPathに区切り文字(\記号および:記号)が含まれない場合はTRUEを返す。
含まれる場合はFALSEを返す。
あくまでも区切り文字とドライブ記号のチェックしかしないので、ファイル名として使用できない文字が含まれていてもTRUE
を返します。
ルートディレクトリのチェック
PathCchIsRoot関数
PathCchIsRoot
関数は、パス文字列がルートディレクトリを示しているか否かを判定します。
- WINPATHCCHAPI BOOL PathCchIsRoot(
PCWSTR pszPath
); - パス文字列pszPathがルートディレクトリならTRUEを返す。
それ以外の場合はFALSEを返す。
ルートディレクトリとは、パスの階層構造の最上位となるディレクトリのことです。
例えば「C:\」「\」などはルートディレクトリとみなされます。
「C:」「C:\abc」「\abc」「abc\def」などはFALSE
になります。
PathIsRoot関数
PathIsRoot
関数は、パス文字列がルートディレクトリを示しているか否かを判定します。
- BOOL PathIsRootW(
LPCWSTR pszPath
); - パス文字列pszPathがルートディレクトリならTRUEを返す。
それ以外の場合はFALSEを返す。
共通のルートをチェック
PathIsSameRoot関数
PathIsSameRoot
関数は、二つのパス文字列が同じルートディレクトリか否かを判定します。
- BOOL PathIsSameRootW(
LPCWSTR pszPath1,
LPCWSTR pszPath2
); - パス文字列pszPathがパス文字列pszPath2と共通のルートを持つ場合はTRUEを返す。
それ以外の場合はFALSEを返す。
指定するパス文字列は絶対パスでなければなりません。
「C:\abc」と「C:\def」の比較はTRUE
を返しますが、「abc\def」と「abc\ghi」の比較ではFALSE
を返します。
共通の接頭辞の検索
PathCommonPrefix関数
PathCommonPrefix
関数は、二つのパス文字列の先頭から共通するパス文字列を調べます。
- int PathCommonPrefixW(
LPCWSTR pszFile1,
LPCWSTR pszFile2,
LPWSTR achPath
); - パス文字列pszFile1とパス文字列pszFile2に共通するパス文字列を検索し、文字列バッファachPathに格納する。
戻り値はバッファachPathの文字数。
この関数は単純に先頭から一致する文字を検索するのではなく、一致するディレクトリ構造を調べます。
一致するものがなかった場合は第三引数achPath
はNULL
になり、0が返されます。
また、achPath
は少なくともMAX_PATH
以上のサイズを確保しておく必要があります。
WCHAR path[MAX_PATH];
int len;
len = PathCommonPrefix(L"C:\\aaa\\bbb", L"C:\\aaa\\ccc", path);
//path = C:\aaa, len = 6
len = PathCommonPrefix(L"C:\\aaax\\bbb", L"C:\\aaay\\ccc", path);
//path = C:\, len = 3
ワイルドカードのテスト
PathMatchSpec関数
PathMatchSpec
関数は、パス文字列がワイルドカードに一致するかを判定します。
- BOOL PathMatchSpecW(
LPCWSTR pszFile,
LPCWSTR pszSpec
); - パス文字列pszFileからワイルドカードパターン文字列pszSpecを検索する。
パターンが一致したらTRUEを、一致しなければFALSEを返す。
ワイルドカードは「?」が任意の一文字、「*」が0文字以上の任意の文字列にマッチします。
BOOL match;
//「.txt」で終わるかをチェック
match = PathMatchSpec(L"C:\\aaa\\file.txt", L"*.txt");
//TRUE
match = PathMatchSpec(L"C:\\aaa\\file.exe", L"*.txt");
//FALSE
//「C:\aaa\」フォルダ内にあるかをチェック
match = PathMatchSpec(L"C:\\aaa\\file.exe", L"C:\\aaa\\*");
//TRUE
match = PathMatchSpec(L"C:\\bbb\\file.exe", L"C:\\aaa\\*");
//FALSE
//「202○.txt」に一致するかをチェック
match = PathMatchSpec(L"2021.txt", L"202?.txt");
//TRUE
match = PathMatchSpec(L"2022.txt", L"202?.txt");
//TRUE
match = PathMatchSpec(L"2019.txt", L"202?.txt");
//FALSE
ルートの除去
PathCchSkipRoot関数
PathCchSkipRoot
関数は、パス文字列からルート文字列を検索し、その次の文字列の位置を取得します。
- WINPATHCCHAPI HRESULT PathCchSkipRoot(
PCWSTR pszPath,
PCWSTR *ppszRootEnd
); - パス文字列pszPathからルート文字列を検索し、その次の文字の位置を文字ポインタppszRootEndに格納する。
成功した場合はS_OKを返す。
失敗した場合はそれ以外の値を返す。
この関数は文字列バッファに変更を加えず、ルート文字列を除いた位置のポインタを取得します。
ルート文字列とは例えば「C:\」「\\server\share\」などです。
得られるポインタの先頭には区切り文字は含まれません。
文字列の先頭がルート文字列でない場合は関数は失敗します。
PathSkipRoot関数
PathSkipRoot
関数は、パス文字列からルート文字列を検索し、その次の文字列の位置を返します。
- LPCWSTR PathSkipRootW(
LPCWSTR pszPath
); - パス文字列pszPathからルート文字列を検索し、その次の文字の位置を返す。
位置ポインタを受け取る方法は異なりますが、動作はPathCchSkipRoot関数と同じです。
ディレクトリの除去
PathStripPath関数
PathStripPath
関数は、パス文字列からディレクトリ部分を取り除きます。
- void PathStripPathW(
LPWSTR pszPath
); - パス文字列pszPathからディレクトリを示す箇所を除去する。
結果として、文字列バッファにはファイル名が格納された状態になります。
区切り文字がない場合やルートディレクトリ名のみを指定した場合は何もしません。
ファイル名の位置のポインタを取得する場合はPathFindFileName関数を使用します。
ルートディレクトリの取得
PathCchStripToRoot関数
PathCchStripToRoot
関数は、パス文字列からルートディレクトリ部分以外を取り除きます。
- WINPATHCCHAPI HRESULT PathCchStripToRoot(
PWSTR pszPath,
size_t cchPath
); - 長さcchPathのパス文字列pszPathからルートディレクトリを示す箇所以外を除去する。
成功した場合はS_OKを返す。
失敗した場合はそれ以外を返す。
PathStripToRoot関数
PathStripToRoot
関数は、パス文字列からルートディレクトリ部分以外を取り除きます。
- BOOL PathStripToRootW(
LPWSTR pszPath
fds ); - パス文字列pszPathからルートディレクトリを示す箇所以外を除去する。
成功した場合はTRUEを、失敗した場合はFALSEを返す。
ルートディレクトリに該当する部分がない場合は文字列はすべて消去されます。
末尾要素の除去
PathCchRemoveFileSpec関数
PathCchRemoveFileSpec
関数は、末尾のファイル名/ディレクトリ名、および区切り文字を取り除きます。
- WINPATHCCHAPI HRESULT PathCchRemoveFileSpec(
PWSTR pszPath,
size_t cchPath
); - 長さcchPathのパス文字列pszPathから、末尾のファイル名またはディレクトリ名と区切り文字を除去する。
成功した場合はS_OKを返す。
失敗した場合はそれ以外の値を返す。
要するに現在の場所からひとつ上の階層に移動した時のパス文字列を取得します。
ルートディレクトリ(ある場合)は除去されずに残ります。
WCHAR path1[MAX_PATH] = L"C:\\aaa\\bbb";
PathCchRemoveFileSpec(path1, MAX_PATH);
//C:\aaa
WCHAR path2[MAX_PATH] = L"C:\\aaa\\bbb\\";
PathCchRemoveFileSpec(path2, MAX_PATH);
//C:\aaa\\bbb
WCHAR path3[MAX_PATH] = L"C:\\";
PathCchRemoveFileSpec(path3, MAX_PATH);
//C:\
WCHAR path4[MAX_PATH] = L"aaa\\bbb";
PathCchRemoveFileSpec(path4, MAX_PATH);
//aaa
WCHAR path5[MAX_PATH] = L"\\aaa";
PathCchRemoveFileSpec(path5, MAX_PATH);
//\
WCHAR path6[MAX_PATH] = L"aaa";
PathCchRemoveFileSpec(path6, MAX_PATH);
//(空文字)
PathRemoveFileSpec関数
PathRemoveFileSpec
関数は、末尾のファイル名/ディレクトリ名、および区切り文字を取り除きます。
- BOOL PathRemoveFileSpecW(
LPWSTR pszPath
); - パス文字列pszPathから、末尾のファイル名またはディレクトリ名と区切り文字を除去する。
成功した場合はTRUEを、失敗した場合はFALSEを返す。
パスの正規化
PathCchCanonicalize関数
PathCchCanonicalize
関数は、パス文字列を正規化します。
- WINPATHCCHAPI HRESULT PathCchCanonicalize(
PWSTR pszPathOut,
size_t cchPathOut,
PCWSTR pszPathIn
); - 長さcchPathOutの文字列バッファpszPathOutに、パス文字列pszPathInを正規化して格納する。
成功した場合はS_OKを返す。
失敗した場合はそれ以外の値を返す。
この場合の正規化とは、ディレクトリの階層構造を示すピリオドを含むパス文字列を展開することを言います。
パス文字列として使用できない文字を取り除いたり、スラッシュをバックスラッシュ(円記号)に置き換えたりはしません。
「.\aaa」は同じ階層の「aaa」ディレクトリ(またはファイル)を意味します。
「..\aaa」はひとつ上の階層の「aaa」ディレクトリ(またはファイル)を意味します。
WCHAR path[MAX_PATH];
PathCchCanonicalize(path, MAX_PATH, L"C:\\aaa\\.\\bbb");
//C:\aaa\bbb
PathCchCanonicalize(path, MAX_PATH, L"C:\\aaa\\..\\bbb");
//C:\bbb
PathCchCanonicalize(path, MAX_PATH, L"C:\\aaa\\bbb\\..\\..\\ccc");
//C:\ccc
PathCchCanonicalize(path, MAX_PATH, L"C:\\aaa\\bbb\\.");
//C:\aaa\bbb
PathCchCanonicalize(path, MAX_PATH, L"C:\\aaa\\bbb\\..");
//C:\aaa
PathCchCanonicalize(path, MAX_PATH, L"C:\\..\\..\\..");
//C:\
PathCchCanonicalize(path, MAX_PATH, L"aaa\\bbb\\..\\..");
//\
PathCanonicalize関数
PathCanonicalize
関数は、パス文字列を正規化します。
- BOOL PathCanonicalizeW(
LPWSTR pszBuf,
LPCWSTR pszPath
); - 文字列バッファpszBufに、パス文字列pszPathを正規化して格納する。
成功した場合はTRUEを、失敗した場合はFALSEを返す。
相対パスのチェック
PathIsRelative関数
PathIsRelative
関数は、パス文字列が相対パスか否かを判定します。
- BOOL PathIsRelativeW(
LPCWSTR pszPath
); - パス文字列pszPathが相対パスならTRUEを返す。
絶対パスならFALSEを返す。
相対パスはたとえば「abc\def」「.\abc」「..\abc」といった形式、および単純なファイル名です。
区切り文字から始まるパス文字列は絶対パスとみなされます。
(Windowsではあり得ませんが、UNIX系では有効な絶対パスです)
相対パスの取得
PathRelativePathTo関数
PathRelativePathTo
関数は、あるパスからもうひとつのパスへの相対パスを取得します。
- BOOL PathRelativePathToW(
LPWSTR pszPath,
LPCWSTR pszFrom,
DWORD dwAttrFrom,
LPCWSTR pszTo,
DWORD dwAttrTo ); - パス文字列pszFromからパス文字列pszToへの相対パスを生成し、文字列バッファpszPathに格納する。
成功した場合はTRUEを、失敗した場合はFALSEを返す。
第一引数pszPath
は生成された文字列を格納するバッファです。
少なくともMAX_PATH
以上のサイズを確保しておく必要があります。
第二引数pszFrom
は起点となるパス文字列、第四引数pszTo
は目的となるパス文字列です。
pszFromからpszToへの相対パス文字列を生成します。
第三引数dwAttrFrom
と第五引数dwAttrTo
は、それぞれpszFromとpszToがディレクトリかファイルかを示す定数を指定します。
ここに定数FILE_ATTRIBUTE_DIRECTORY
を指定するとパスはディレクトリであるとみなされます。
それ以外を指定するとファイルとみなされます。
WCHAR path[MAX_PATH];
PathRelativePathTo(path,
L"C:\\aaa\\", FILE_ATTRIBUTE_DIRECTORY,
L"C:\\aaa\\bbb", FILE_ATTRIBUTE_DIRECTORY);
//.\bbb
PathRelativePathTo(path,
L"C:\\aaa\\bbb", FILE_ATTRIBUTE_DIRECTORY,
L"C:\\aaa", FILE_ATTRIBUTE_DIRECTORY);
//..
PathRelativePathTo(path,
L"C:\\aaa\\bbb", FILE_ATTRIBUTE_DIRECTORY,
L"C:\\aaa\\ccc", FILE_ATTRIBUTE_DIRECTORY);
//..\ccc
PathRelativePathTo(path,
L"aaa\\bbb", FILE_ATTRIBUTE_DIRECTORY,
L"aaa\\ccc", FILE_ATTRIBUTE_DIRECTORY);
//..\ccc
PathRelativePathTo(path,
L"C:\\aaa", FILE_ATTRIBUTE_DIRECTORY,
L"D:\\aaa", FILE_ATTRIBUTE_DIRECTORY);
//※関数失敗
//異なるドライブへの相対パスは作成できない
PathRelativePathTo(path,
L"aaa\\bbb", FILE_ATTRIBUTE_DIRECTORY,
L"ccc\\ddd", FILE_ATTRIBUTE_DIRECTORY);
//※関数失敗
//共通のディレクトリがないため相対的な位置がわからない
パスには相対パスを指定することも可能ですが、先頭のディレクトリは共通である必要があります。
URL形式のチェック
PathIsURL関数
PathIsURL
関数は、パス文字列がURL形式か否かを判定します。
- BOOL PathIsURLW(
LPCWSTR pszPath
); - パス文字列pszPathが有効なURL形式ならTRUEを返す。
絶対パスならFALSEを返す。
URL形式とは例えば「http:」などから始まる文字列です。
この関数は「C:」はFALSEになりますが、「CC:」「123:」などはTRUEとなります。
コロン以降の文字列のチェックも行わないので、一般的なウェブサイトのアドレス形式のチェックとしては使えません。
パスの結合
PathCchCombine関数
PathCchCombine
関数は、二つのパス文字列を結合します。
- WINPATHCCHAPI HRESULT PathCchCombine(
PWSTR pszPathOut,
size_t cchPathOut,
PCWSTR pszPathIn,
PCWSTR pszMore
); - 長さcchPathOutの文字列バッファpszPathOutに、パス文字列pszPathInとパス文字列pszMoreを結合して格納する。
成功した場合はS_OKを返す。 失敗した場合はそれ以外の値を返す。
戻り値は以下の定数のいずれかです。
定数 | 説明 |
---|---|
S_OK | 関数の成功。 |
E_OUTOFMEMORY | メモリ不足エラー。 |
PATHCCH_E_FILENAME_TOO_LONG | パス文字列のサイズが大きすぎる。 ( PATHCCH_MAX_CCH を超えた) |
E_INVALIDARG | その他のエラー。 |
パスを結合する関数は単純な文字列の結合ではなく、パスの整合性を考慮して結合されます。
区切り文字が必要な場合は自動で挿入されます。
第三引数第三引数pszPathIn
が相対パスを示す「.\」「..\」から始まる場合は除去されます。
第四引数pszMore
の相対パスの指定は結果に反映されます。
WCHAR path[MAX_PATH];
PathCchCombine(path, MAX_PATH, L"C:\\aaa\\bbb", L"ccc\\ddd");
//pathには「C:\aaa\bbb\ccc\ddd」が格納される
PathCchCombine(path, MAX_PATH, L"..\\aaa\\bbb", L"ccc\\ddd");
//pathには「aaa\bbb\ccc\ddd」が格納される
PathCchCombine(path, MAX_PATH, L"aaa\\bbb", L"..\\ccc\\ddd");
//pathには「aaa\ccc\ddd」が格納される
//(「..\」はひとつ上の階層を意味する)
第四引数pszMore
に区切り文字から始まる文字列を指定すると、第三引数pszPathIn
のルート(ドライブ文字列)と結合した文字列が作成されます。
第三引数が相対パスの場合は関数は失敗します。
WCHAR path[MAX_PATH];
PathCchCombine(path, MAX_PATH, L"C:\\aaa\\bbb", L"\\ccc\\ddd");
//pathには「C:\ccc\ddd」が格納される
第四引数pszMore
に絶対パスを指定すると第四引数のパス文字列がそのままバッファにコピーされます。
(第三引数は無視される)
この関数は第一引数と第三引数or第四引数に同じ変数を指定することができます。
WCHAR path[MAX_PATH] = L"C:\\aaa\\bbb";
PathCchCombine(path, MAX_PATH, path, L"ccc\\ddd");
PathCombine関数
PathCombine
関数は、二つのパス文字列を結合します。
- LPWSTR PathCombineW(
LPWSTR pszDest,
LPCWSTR pszDir,
LPCWSTR pszFile
); - 文字列バッファpszDestに、パス文字列pszDirとパス文字列pszFileを結合して格納する。
成功した場合はpszDestへのポインタを、失敗した場合はNULLを返す。
PathCchAppend関数
PathCchAppend
関数は、二つのパス文字列を結合します。
- WINPATHCCHAPI HRESULT PathCchAppend(
PWSTR pszPath,
size_t cchPath,
PCWSTR pszMore
); - 長さcchPathの文字列バッファpszPathの末尾にパス文字列pszMoreを結合する。
成功した場合はS_OKを、失敗した場合はそれ以外を返す。
パス結合のルールはPathCchCombine関数と基本的に同じですが、第三引数pszMore
に区切り文字から始まるパスを指定した場合の動作は異なります。
PathCchCombine関数の場合は先頭パスのルート文字列と追加のパスが結合されますが、PathCchAppend関数では単純にパスの結合になります。
WCHAR path[MAX_PATH] = L"C:\\aaa\\bbb";
PathCchAppend(path, MAX_PATH, L"\\ccc\\ddd");
//pathには「C:\aaa\bbb\ccc\ddd」が格納される
PathCchCombine(path, MAX_PATH, L"C:\\aaa\\bbb", L"\\ccc\\ddd");
//pathには「C:\ccc\ddd」が格納される
PathAppend関数
PathAppend
関数は、二つのパス文字列を結合します。
結合のルールはPathCchAppend関数と同じです。
- BOOL PathAppendW(
LPWSTR pszPath,
LPCWSTR pszMore
); - 文字列バッファpszPathの末尾にパス文字列pszMoreを結合する。
成功した場合はTRUEを、失敗した場合はFALSEを返す。