在C++中字符串类的string的模板原型是basic_string

template <class _Elem, class traits = char_traits<_Elem>, class _Ax = allocator<_Elem>>
class basic_string{};

第一个参数_Elem表示类型。第二个参数traits的缺省值使用char_traits类型,定义了类型和字符操作的函数,如比较、等价、分配等。第三个参数_Ax的默认值是allocator类,表示了内存模式,不同的内存结构将操作指针的不同行为,例如栈、堆或段内存模式等。

在C++标准里定义了两个字符串string和wstring

typedef basic_string<char> string;
typedef basic_string<wchar_t> wstring;

前者string是常用类型,可以看作char[],其实这正是与string定义中的_Elem=char相一致。而wstring,使用的是wchar_t类型,这是宽字符,用于满足非ASCII字符的要求,例如Unicode编码,中文,日文,韩文什么的。对于wchar_t类型,实际上C++中都用与char函数相对应的wchar_t的函数,因为他们都是从同一个模板类似于上面的方式定义的。因此也有wcout, wcin, werr等函数。

实际上string也可以使用中文,但是它将一个汉字写在2个char中。而如果将一个汉字看作一个单位wchar_t的话,那么在wstring中就只占用一个单元,其它的非英文文字和编码也是如此。这样才真正的满足字符串操作的要求,尤其是国际化等工作。

看一下下面的程序,就会理解两者的差别。


#include <iostream>
#include <string>
using namespace std; #define tab "\t" int main()
{
    locale def;
    cout<<def.name()<<endl;
    locale current = cout.getloc();
    cout<<current.name()<<endl;     float val=1234.56;
    cout<<val<<endl;     //chage to french/france
    cout.imbue(locale("chs"));
    current=cout.getloc();
    cout<<current.name()<<endl;
    cout<<val<<endl;     //上面是说明locale的用法,下面才是本例的内容,因为其中用到了imbue函数
    cout<<"*********************************"<<endl;     //为了保证本地化输出(文字/时间/货币等),chs表示中国,wcout必须使用本地化解析编码
    wcout.imbue(std::locale("chs"));     //string 英文,正确颠倒位置,显示第二个字符正确
    string str1("ABCabc");
    string str11(str1.rbegin(),str1.rend());
    cout<<"UK\ts1\t:"<<str1<<tab<<str1[1]<<tab<<str11<<endl;     //wstring 英文,正确颠倒位置,显示第二个字符正确
    wstring str2=L"ABCabc";
    wstring str22(str2.rbegin(),str2.rend());
    wcout<<"UK\tws4\t:"<<str2<<tab<<str2[1]<<tab<<str22<<endl;     //string 中文,颠倒后,变成乱码,第二个字符读取也错误
    string str3("你好么?");
    string str33(str3.rbegin(),str3.rend());
    cout<<"CHN\ts3\t:"<<str3<<tab<<str3[1]<<tab<<str33<<endl;     //正确的打印第二个字符的方法
    cout<<"CHN\ts3\t:RIGHT\t"<<str3[2]<<str3[3]<<endl;     //中文,正确颠倒位置,显示第二个字符正确
    wstring str4=L"你好么?";
    wstring str44(str4.rbegin(),str4.rend());
    wcout<<"CHN\tws4\t:"<<str4<<tab<<str4[1]<<tab<<str44<<endl;     wstring str5(str1.begin(),str1.end());//只有char类型的string时才可以如此构造
    wstring str55(str5.rbegin(),str5.rend());
    wcout<<"CHN\tws5\t:"<<str5<<tab<<str5[1]<<tab<<str55<<endl;     wstring str6(str3.begin(),str3.end());//如此构造将失败!!!!
    wstring str66(str6.rbegin(),str6.rend());
    wcout<<"CHN\tws6\t:"<<str6<<tab<<str6[1]<<tab<<str66<<endl;     return 0;
}

结果如下:

上面显示了本地化的作用,是在数字中每三位加一个逗号,其实对时间/文字等都是用影响的。

下面的输出说明了,如何正确使用string和wstring的方法。第三个因为使用string来表示汉字,出现了一些错误。最后一行也是错误,导致了输出也受到了影响,没有空格与回车。(最后两个就不要管中英文了,仅仅说明一下中文构造方法是错误的)

《掌握标准C++类》在第十二章《语言支持》中专门讲C++的国际化和本地化问题,C++提供了I18N的标准处理,软件开发者可以参考。

C++标准库还是非常博大精深的,功能比较齐全的。继续学习。

http://www.cnblogs.com/xiaoyz/archive/2008/10/11/1308860.html

C++的中英文字符串表示(string,wstring),使用wcout.imbue(std::locale("chs"));本地化解析编码的更多相关文章

  1. C++的中英文字符串表示(string,wstring)

    在C++中字符串类的string的模板原型是basic_string template <class _Elem, class traits = char_traits<_Elem> ...

  2. android上让我放弃使用wstring来操作中英文字符串 转

    android上让我放弃使用wstring来操作中英文字符串 2013-08-07 16:37:24|  分类: cocos2d|举报|字号 订阅     项目需要,需要对中英文字符串进行遍历修改等, ...

  3. php截取中文字符串,英文字符串,中英文字符串长度的方法

    今天学习了php函数截取中文字符串,英文字符串,中英文字符串的函数使用方法.对中英文截取方法不理解,此处先做记录. PHP自带的函数如strlen().mb_strlen()都是通过计算字符串所占字节 ...

  4. [技术] OIer的C++标准库 : 字符串库<string>

    引入 上次我在博客里介绍了OI中可能用到的STL中的功能, 今天我们接着来发掘C++标准库中能为OI所用的部分. 众所周知, OI中经常用到字符串相关的处理, 这时善用字符串库可以使一些操作更加简洁易 ...

  5. JavaScript截取中英文字符串

    有时在显示某段文字的时候,可能会太长,影响我们页面的显示效果.如果仅是英文,那么我们可以用String.substring(start, end)函数就已经够用了.但是通常我们都会遇到既有英文,又有汉 ...

  6. js截取中英文字符串、标点符号无乱码示例解读

    <script> function subString(str, len, hasDot) { var newLength = 0; var newStr = ""; ...

  7. ASP.NET MVC 5 - 创建连接字符串(Connection String)并使用SQL Server LocalDB

    您创建的MovieDBContext类负责处理连接到数据库,并将Movie对象映射到数据库记录的任务中.你可能会问一个问题,如何指定它将连接到数据库? 实际上,确实没有指定要使用的数据库,Entity ...

  8. 窥探Swift之字符串(String)

    之前总结过Objective-C中的字符串<Objective-C精选字符串处理方法>,学习一门新语言怎么能少的了字符串呢.Swift中的String和Objective-C语言中NSSt ...

  9. 数据结构和算法 – 4.字符串、 String 类和 StringBuilder 类

    4.1.String类的应用 class String类应用 { static void Main(string[] args) { string astring = "Now is The ...

随机推荐

  1. Android自定义组件系列【1】——自定义View及ViewGroup

    View类是ViewGroup的父类,ViewGroup具有View的所有特性,ViewGroup主要用来充当View的容器,将其中的View作为自己孩子,并对其进行管理,当然孩子也可以是ViewGr ...

  2. tig install ncursesw

    ./configure --prefix=/home/xxx/.local/ --with-ncursesw make[xxx$ ldd src/tig linux-vdso.so.1 => ( ...

  3. 《从零開始学Swift》学习笔记(Day 71)——Swift与C/C++混合编程之数据类型映射

    原创文章.欢迎转载.转载请注明:关东升的博客 posted @ 2017-07-21 13:23 zhchoutai 阅读(...) 评论(...) 编辑 收藏

  4. [Angular] Angular CLI

    Create an app with routing config: ng new mynewapp --routing If you want to generate a new module wi ...

  5. php如何实现把多平台文件中所有的行合成一行?

    php如何实现把多平台文件中所有的行合成一行? 一.总结 1.str_replace中的数组替换:str_replace(array("/r","/n",&qu ...

  6. mysqlsla slow-query常用用法

    mysqlsla -lt slow /data/mysql/testdb2-slow.log -sf -top 20 -sort t_sum > /data/mysql/my_testdb2-s ...

  7. 01_Git的安装和简单使用(命令行模式+图形化模式)

      刚开始用git的小白适用,参考链接:http://www.cnblogs.com/qijunjun/p/7137207.html  实际项目开发中,我们经常会用一些版本控制器来托管自己的代码,今天 ...

  8. Maven学习笔记(六):生命周期与插件

    何为生命周期:      Maven的生命周期就是为了对全部的构建过程进行抽象和统一.Maven从大量项目和构建工具中学习和反思,然后总结了一套高度完好的.易扩展的生命周期.这个生命周期包括了项目的清 ...

  9. Windows 平台下 LiteIDE 的安装和使用

    1. 安装 Go 语言并设置环境变量 参考博客<Windows 平台下 Go 语言的安装和环境变量设置>. 2. MinGW 的下载和安装 Windows 下的 Go 调试还需要安装 Mi ...

  10. freemarker中间split字符串切割

    freemarker中间split字符串切割 1.简易说明 split切割:用来依据另外一个字符串的出现将原字符串切割成字符串序列 2.举例说明 <#--freemarker中的split字符串 ...