2011-03-15 33 views
9

下面的程序在Visual Studio 2008編譯Windows下下,都與字符集 「使用Unicode字符集」和「使用多字節字符集」。但是,它不能在Ubuntu 10.04.2 LTS 64位和GCC 4.4.3下編譯。我在兩種環境下都使用Boost 1.46.1。的boost ::文件系統和Unicode Linux和Windows

#include <boost/filesystem/path.hpp> 
#include <iostream> 

int main() { 
    boost::filesystem::path p(L"/test/test2"); 
    std::wcout << p.native() << std::endl; 
    return 0; 
} 

Linux下的編譯錯誤是:

TEST.CPP:6:錯誤:不對應的在「的std :: '運算符< <' wcout < < p.boost :: filesystem3 ::路徑::本地()」

它看起來對我來說,升壓:: Linux下的文件系統不提供路徑)寬字符的字符串::本地(儘管已用初始化的boost ::文件系統::路徑寬字符串。此外,我猜測這是因爲Linux默認爲UTF-8,Windows默認爲UTF-16。

所以我的第一個問題是,我怎麼寫這兩個平臺上使用的boost ::文件系統,並支持Unicode路徑的程序?

第二個問題:當我在Windows下運行此程序,它輸出:

/test/test2 

我的理解是,本地()方法應該將路徑轉換到Windows下的原生格式,這是使用反斜槓代替正斜槓。爲什麼字符串以POSIX格式出現?

回答

2

你的native認識不完全正確:

本地路徑格式:實現定義的格式。 [注意:對於POSIX類操作系統,本機格式與通用格式相同。對於Windows,本機格式與通用格式類似,但目錄分隔符可以是斜線或反斜線。 - 注完]

Reference

這是因爲Windows允許POSIX風格的路徑名,所以使用native()不會造成上述問題。

因爲你可能經常會與你的輸出類似的問題,我認爲最好的辦法是使用你的預處理,即:

#ifdef WINDOWS 
std::wostream& console = std::wcout; 
#elif POSIX 
std::ostream& console = std::cout; 
#endif 

和串級類似的東西。

+0

謝謝您的回答。再看看這一點,看起來使用cout而不是寬字符是Linux中的一種方式,因爲在那裏所有的東西都是UTF-8。但在Windows控制檯中,使用wcout雖然會編譯,但不能正確顯示Unicode字符。爲了實現這一目標,顯然有幾個環節必須跳過。 – 2011-03-17 05:40:31

+0

Windows控制檯能夠以UTF-16格式顯示Unicode,但其默認字體不可用,必須將控制檯設置更改爲Unicode字體。同樣根據我的經驗,即使您通過UTF-16並且輸出爲UTF-16,通過Windows的C I/O函數的所有路由也會愚蠢地通過非Unicode的8位編碼瓶頸!您可能能夠做一些設置並傳遞一些參數以避免它......但調用「寬」Windows控制檯輸出API要容易得多。 – hippietrail 2012-08-13 08:31:52

1

如果你要使用的寬輸出流,你要轉換成寬字符串:

#include <boost/filesystem/path.hpp> 
#include <iostream> 

int main() { 
    boost::filesystem::path p(L"/test/test2"); 
    std::wcout << p.wstring() << std::endl; 
    return 0; 
} 

注意,據我所知使用wcout不給你在Windows的Unicode輸出;您需要改用wprintf

+1

謝謝你的回答。我已經對wcout進行了一些研究,看來它只是在將結果的窄字符發送到標準輸出之前刪除高字節來將寬字符轉換爲窄字符。顯然,這是如何在C++標準庫中定義wcout,但我還沒有能夠驗證這一點。如果是這樣,wcout在任何平臺上都沒有做任何有用的事情。 – 2011-03-17 05:15:26

+0

path :: string()在功能上不等同於path:native()。想知道爲什麼沒有路徑:: wnative()? – 2011-03-17 05:27:09

+0

@Roger:「wcout在任何平臺上都沒有做任何有用的工作。」 - 我同意。要在Windows中打印Unicode字符串,您必須使用['wprintf'](http://blogs.msdn.com/b/michkap/archive/2008/03/18/8306597.aspx)。關於'wnative':根據定義,每個平臺上只有一個規範的本機格式,可以是寬(Windows)或窄字符串(Unix)。 – Philipp 2011-03-17 13:36:44

0

試試這個:

#include <boost/filesystem/path.hpp> 
#include <iostream> 

int main() { 
    boost::filesystem::path p("/test/test2"); 
    std::wcout << p.normalize() << std::endl; 
    return 0; 
}