zoukankan      html  css  js  c++  java
  • [译][boost]Boost.Nowide

    翻译源 http://cppcms.com/files/nowide/html/
    版权归原作者Artyom Beilis所有

    =是什么=

    该库提供标准C和C++的库函数的一种实现,这些函数在windows下的输入是UTF-8,而不使用Wide API(Windows函数是区分字符集的:A表示ANSI,W表示Wide,即Unicode)。

    =要解决的问题=

    考虑一个简单的应用,它将大文件分块,以便将其通过e-mail发送。它需要做简单的几步:
    * 访问命令行参数 int main(int argc, char** argv)
    * 打开输入文件,打开多个输入文件:std::fstream::open(char const *, std::ios::openmode m)
    * 出错时移除文件:std::remove(char const* file)
    * 向控制台打印进度:std::cout << file_name
    不幸的是,如果文件名称包含非ASCII字符时,只使用原生C++是不可能实现这个简单任务的。
    这个使用API的简单程序在那些内部使用UTF-8的系统(大多数的Unix类OS)中能够运行。但在Winsows系统下会在处理某些名称的文件时失败,因为本地Windows Unicode API是Wide-API - UTF16。
    这个琐碎的功能在跨平台移植时非常难以处理。

    =解决方案=

    本库提供一组基于UTF-8的标准库函数,使得Unicode敏感的编程更为容易。
    本库提供:
    * 易用的UTF-8到UTF-16互相转换的函数
    * 一个类,修正argc,argv和环境变量主参数使用UTF-8
    * UTF-8敏感函数:
    # stdio.h函数
    # stdlib.h函数
    # fstream
    # iostream

    =为什么不用Narrow和Wide?=

    几个原因:
    * wchar_t并不是真正的跨平台,可能是2字节,4字节,甚至是1字节
    * 标准C和C++库在OS交互中使用narrow string。本库遵循相同规则。相对于重新以Windows Style实现Wide API,坚持标准方法是更好的选择。

    =使用本库=
    基本上本库是头文件,只有控制台I/O需要在Windows下单独编译。
    作为开发者,我们认为你应当使用boost::nowide函数,而不应当用std名字空间中的函数。
    例如,Unicode不敏感的实现:

    #include <fstream>
    #include <iostream>
    int main(int argc,char **argv)
    {
        if(argc!=2) {
            std::cerr << "Usage: file_name" << std::endl;
            return 1;
        }
        std::ifstream f(argv[1]);
        if(!f) {
            std::cerr << "Can't open a file " << argv[1] << std::endl;
            return 1;
        }
        int total_lines = 0;
        while(f) {
            if(f.get() == '\n')
                total_lines++;
        }
        f.close();
        std::cout << "File " << argv[1] << " has " << total_lines << " lines" << std::endl;
        return 0;
    }
    

    处理Unicode时,作如下更改:

    #include <boost/nowide/args.hpp>
    #include <boost/nowide/fstream.hpp>
    #include <boost/nowide/iostream.hpp>
    int main(int argc,char **argv)
    {
        boost::nowide::args a(argc,argv); // Fix arguments - make them UTF-8
        if(argc!=2) {
            boost::nowide::cerr << "Usage: file_name" << std::endl; // Unicode aware console
            return 1;
        }
        boost::nowide::ifstream f(argv[1]); // argv[1] - is UTF-8
        if(!f) {
            // the console can display UTF-8
            boost::nowide::cerr << "Can't open a file " << argv[1] << std::endl;
            return 1;
        }
        int total_lines = 0;
        while(f) {
            if(f.get() == '\n')
                total_lines++;
        }
        f.close();
        // the console can display UTF-8
        boost::nowide::cout << "File " << argv[1] << " has " << total_lines << " lines" << std::endl;
        return 0;
    }
    

    =windows.h头文件=

    本库并未包含windows.h,以免名字空间污染。本库自行定义了Win32 API函数的原型。
    但是,如果你也想使用原生的windows.h头文件,你需要在包含Boost.Nowide头文件前设置BOOST_NOWIDE_USE_WINDOWS_H定义。

    =技术细节=

    1. Windows vs POSIX
    Windows平台,本库在名字空间boost::nowide下提供UTF-8敏感的函数,通常情况下这些函数在名字空间std::下。
    POSI平台,boost::nowide::fopen和所有其它函数都是标准库函数的别名:
    namespace boost {
    namespace nowide {
    #ifdef BOOST_WINDOWS
    inline FILE *fopen(char const *name,char const *mode)
    {
    ...
    }
    #else
    using std::fopen
    #endif
    } // nowide
    } // boost

    2. 控制台I/O
    控制台I/O实现了ReadConsoleW/WriteConsoleW的封装,除非流不是“atty”的,例如管道。
    这种方法排除了手工进行编码页处理。

  • 相关阅读:
    6:python2、python3 的区别及小数据池
    web前端----html表单操作
    web前端----html基础
    mysql数据库----索引原理与慢查询优化
    MySQL数据库----流程控制
    MySQL数据库----IDE工具介绍及数据备份
    MySQL数据库----数据锁
    MySQL数据库----事务处理
    MySQL数据库----事务
    MySQL数据库----函数
  • 原文地址:https://www.cnblogs.com/result/p/4860289.html
Copyright © 2011-2022 走看看