Re: [問題] boost::filesystem 路徑問題 (許功蓋相關)

看板C_and_CPP (C/C++)作者 (null)時間16年前 (2009/08/10 00:54), 編輯推噓1(106)
留言7則, 3人參與, 最新討論串2/2 (看更多)
Hello, 重新測試後發現,其實在 WinXP Big5 環境下,對於許功能等字雖然能正常處理, 但似乎會影響到下一次 iteration 的結果。 我建立的 test_folder 結構如下: test_folder/ 功能總覽/ 功能總覽/a.txt 功能總覽/b.txt 另一個資料夾/ a.txt 當我想起你.txt 使用下列程式測試: ================================================ 測試程式 = [START] ======== #include <iostream> #include <string> #include "boost/filesystem.hpp" #include "boost/progress.hpp" namespace fs = boost::filesystem; int main(void) { boost::progress_timer t(std::clog); fs::recursive_directory_iterator end; fs::path path("d:\\test_folder"); fs::recursive_directory_iterator iter(path); while (iter != end) { fs::path p; try { p = *iter; if (fs::is_directory(p)) { std::cout << p.directory_string() << " [directory]" << std::endl; } if (fs::is_regular(p)) { std::cout << p.file_string() << " [file]" << std::endl; } iter++; } catch (const std::exception & ex) { std::cerr << ex.what() << std::endl; break; } } return EXIT_SUCCESS; } ================================================ 測試程式 = [END] ======== 測試結果為: C:\demo-room-workspace\native.impl>impl d:\test_folder\a.txt [file] d:\test_folder\功能總覽 [directory] d:\test_folder\功能總覽\a.txt [file] d:\test_folder\功能總覽\b.txt [file] boost::filesystem::basic_directory_iterator constructor: 系統找不到指定的路徑 。: "d:\test_folder\功另一個資料夾" 0.02 s 顯然在前一個路徑的「功」,竟然遺留在「另一個資料夾」的前面。 搜尋 boost::filesytem::path 相關的程式碼,覺得問題可能出在下面這段 code: http://pastie.org/577538 ======================================================================= // from boost "libs/filesystem/src/path.cpp" namespace { // std::locale construction can throw (if LC_MESSAGES is wrong, for example), // so a static at function scope is used to ensure that exceptions can be // caught. (A previous version was at namespace scope, so initialization // occurred before main(), preventing exceptions from being caught.) std::locale & loc() { #if !defined(macintosh) && !defined(__APPLE__) && !defined(__APPLE_CC__) // ISO C calls this "the locale-specific native environment": static std::locale lc(""); #else static std::locale lc = std::locale(); // Mac OS doesn't support locale("") #endif return lc; } const std::codecvt<wchar_t, char, std::mbstate_t> *& converter() { static const std::codecvt<wchar_t, char, std::mbstate_t> * cvtr( &std::use_facet<std::codecvt<wchar_t, char, std::mbstate_t> > ( loc() ) ); return cvtr; } bool locked(false); } // unnamed namespace // ========== call converter (in the same file ) ========== wpath_traits::external_string_type wpath_traits::to_external( const wpath & ph, const internal_string_type & src ) { locked = true; std::size_t work_size( converter()->max_length() * (src.size()+1) ); boost::scoped_array<char> work( new char[ work_size ] ); std::mbstate_t state = std::mbstate_t(); // perhaps unneeded, but cuts bug reports const internal_string_type::value_type * from_next; external_string_type::value_type * to_next; if ( converter()->out( state, src.c_str(), src.c_str()+src.size(), from_next, work.get(), work.get()+work_size, to_next ) != std::codecvt_base::ok ) boost::throw_exception( boost::filesystem::wfilesystem_error( "boost::filesystem::wpath::to_external conversion error", ph, system::error_code( system::posix::invalid_argument, system::system_category ) ) ); *to_next = '\0'; return external_string_type( work.get() ); } ======================================================================== 弟對於 cpp 不太熟悉,想請有經驗的版友們給點意見。 雖然我覺得問題出在 converter() 但也可能是錯誤的判斷, 只能期望初步的 trace 能逼近問題些 :D -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 61.231.48.9

08/10 05:41, , 1F
我猜一下原因: 刪除最近層目錄時是搜尋最右邊的 \ 再砍掉
08/10 05:41, 1F

08/10 05:41, , 2F
所以以此例來說它就以為上一層叫 "d:\test_folder\?"
08/10 05:41, 2F

08/10 05:41, , 3F
(那個 ? 是功的前半字) 然後再加 \ 再找下一層
08/10 05:41, 3F

08/10 05:42, , 4F
理論上是可以改成各層記下自己這一層的目錄名長度來修正
08/10 05:42, 4F

08/10 09:57, , 5F
LPH66 的推測蠻合理的,我想辦法驗證看看 :)
08/10 09:57, 5F

08/10 23:06, , 6F
感謝 LPH66 的推論 http://pastie.org/578534
08/10 23:06, 6F

08/11 22:04, , 7F
如果改成寬字元版本不知能否解決
08/11 22:04, 7F
文章代碼(AID): #1AVlzMCu (C_and_CPP)
文章代碼(AID): #1AVlzMCu (C_and_CPP)