質問: boost::filesystem; int main() { bf::path root("c:\\some\\deep\\application\\folder"); bf::path subdir("..\\configuration\\instance"); bf::path cfgfile("..\\instance\\myfile.cfg"); bf::path final ( root / subdir / cfgfile); cout << final.file_string(); } _最終的なパスは次のように出力されます。_c:\some\deep\application\folder\..\configuration\instance\..\instance\myfile.cfg _これは有効なパスですが、ユーザーに表示するときはnormalized。にすることをお勧めします。 。このような:_c:\some\deep\application\configuration\instance\myfile.cfg _boostの以前のバージョンにはnormalize()関数がありましたが、廃止され、削除されたようです(説明なし)。_boost_filesystem_no_deprecated_マクロを使用しない理由はありますか? boost filesystemライブラリでこれを行う別の方法はありますか?または、パスを文字列として直接操作するコードを記述する必要がありますか?
回答: 「正規」関数は存在するパスでのみ機能するため、パスをその部分に分割し、すべての部分を次の部分と比較する独自のソリューションを作成しました。これをboost 1.55で使用しています。typedef boost::filesystem::path pathtype; template <template <typename t, typename = std::allocator<t> > class container> container<pathtype> splitpath(const pathtype& path) { container<pathtype> ret; long the_size = std::distance(path.begin(),path.end()); if(the_size == 0) return container<pathtype>(); ret.resize(the_size); std::copy(path.begin(),path.end(),ret.begin()); return ret; } pathtype normalizepath(const pathtype& path) { pathtype ret; std::list<pathtype> splitpath = splitpath<std::list>(path); for(std::list<pathtype>::iterator it = (path.is_absolute() ? ++splitpath.begin() : splitpath.begin()); it != splitpath.end(); ++it) { std::list<pathtype>::iterator it_next = it; ++it_next; if(it_next == splitpath.end()) break; if(*it_next == "..") { it = splitpath.erase(it); it = splitpath.erase(it); } } for(std::list<pathtype>::iterator it = splitpath.begin(); it != splitpath.end(); ++it) { ret /= *it; } return ret; } これを使用するために、これを呼び出す方法の例を次に示します。std::cout<<normalizepath("/home/../home/thatfile/")<<std::endl;