2011-03-15 20 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; 
}