1.基本概念与作用

原生字符串(Raw String)指不进行转义“所见即所得”的字符串。很多编程语言早已支持原生字符串,如C#、Python、Shell等。C++作为一门高级程序设计语言,自然不能自甘落后,从C++11开始,C++也开始支持原生字符串。

很多时候,当我们需要一行字符串的时候,字符串转义往往成了一个负担,写和读都带了很大的不便。例如,对于如下路径"D:\workdataDJ\code\vas_pgg_proj",我们必须通过反斜杠进行转义,把它写成如下形式:

string path = "D:\\workdataDJ\\code\\vas_pgg_proj";

可能你会说这个并没有多大影响,但当我们使用正则表达式时,由于正则表达式中特殊字符(如反斜杠、双引号等)较多,再使用反斜杠进行转义,那么正则表达式的可读性将变得很差,形如下面的一条正则表达式。

string re = "('(?:[^\\\\']|\\\\.)*'|\"(?:[^\\\\\"]|\\\\.)*\")|";

在C#中,我们可以通过@关键字来取消字符串转义。在C++11中,它的非转义形式为:

string path = R"(D:\workdataDJ\code\vas_pgg_proj)";

从上面的例子中可以看出,C++的语法格式如下:
(1)字符串前加R前缀;
(2)字符串首尾加上小括号;
它的语法格式比C#的@前缀要稍微复杂点,不过这个复杂也有复杂的好处,那就是字符串里面可以带双引号。

string path = R"(this "word" is escaped)";

而C#无法保持原始字符串格式,对双引号仍需要转义:

string path = @"this ""word"" is escaped";

2.原生字符串与Unicode字符串结合

由于C++11对Unicode的支持,原生字符串的定义方式可以与Unicode字符串结合使用,定义UTF-8、UTF-16和UTF-32的原生字符串,将其前缀分别设置为u8R、uR和UR即可。有一点需要注意,使用了原生字符串,转义字符就不能再使用了,这会给使用\u或者\U的方式书写Unicode字符的程序带来一定影响。参看下面的例子。

#include <iostream>
using namespace std;int main()
{cout<<u8R"(\u4F60,\n\u597D)"<<endl;cout << u8R"(你好)" << endl;cout << sizeof(u8R"(hello)") << "\t" << u8R"(hello)" << endl;cout << sizeof(uR"(hello)") << "\t" << uR"(hello)" << endl;cout << sizeof(UR"(hello)") << "\t" << UR"(hello)" << endl;
}

程序输出结果:

\u4F60,\n\u597D
你好
6       hello
12      00C03174
24      00C03180

从结果可以看出,使用\u定义Unicode字符时,输出原生字符串的模样。在使用sizeof运算符计算不同编码的相同字符串时,得到的结果是不通的,大小跟其申明的类型是完全一致的。注意在使用cout对UTF-16和UTF-8编码的字符串进行输出时,输出的是字符串地址。

3.原生字符串的连接

C++中同样可以将原生字符串进行连接,但不要将不同编码的字符串进行连接,因为C++尚不支持这种做法。考察如下代码:

#include <iostream>
using namespace std;int main()
{char string[] = R"(你好)"R"(=hello)";char u8u8string[] = u8R"(你好)"u8R"(=hello)";//char u8ustring[] = u8R"(你好)"uR"=hello";  //编译报错cout << string<< endl;cout << u8string << endl;cout << sizeof(string) << endl;cout << sizeof(u8u8string) << endl;return 0;
}
//程序编译选项:g++ -finput-charset=utf-8 test.cpp

代码输出结果如下:

你好=hello
你好=hello
13
13

可以看出,原生字符串会被编译器自动连接在一起,整个字符串“你好=hello”含有两个UTF-8编码的中文字符,共占6字节,和6个ASCII字符,再加上自动生成的空字符\0,字符串共占用13字节空间。UTF-8与UTF-16两种不同编码的字符在连接时,编译报错,C++目前还不支持这种写法,请避免。


参考文献

[1]深入理解C++11[M].8.4原生字符串字面量

C++11 原生字符串相关推荐

  1. python原生字符串可以参与比较_正则表达式中对于原生字符串的理解

    在正则表达式中,有些字符是有特殊意义的字符.因此如果想要匹配这些字符,那么就必须使用反斜杠进行转义.比如$代表的是以...结尾,如果想要匹配$,那么就必须使用\$.示例代码如下: text = &qu ...

  2. (一)C++11 原生标准多线程:认识多线程

    之所以称之为C++11原生标准多线程,因为在C++中C++11版本才加入的多线程.所谓原生也就是C++语言自带的,区别于其他库实现,比如POSIX,Boost,winAPI,QT[藐视很少有人提到QT ...

  3. C语言基础之11:字符串和字符串函数

    Tips1: 函数:gets().gets_s().fgets().puts().fputs().strcat().strncat(). strcmp().strncmp().strcpy().str ...

  4. Java 11:字符串类中的新方法

    Java 11 doesn't have a lot of language specific features. So, it was surprising to see 6 new methods ...

  5. Android10/11 原生Launcher3深度定制开发

    一.引言 关于Android10和11系统Launcher3的定制有很多,根据项目的需求会进行各种定制开发, 于是就需要研究Launcher3的源码.本文主要从Android 11的Launcher3 ...

  6. 11、字符串去除空格

    编程题目: 11.写一个函数去掉一个字符串中单词间多余的空格,使得相邻两个单词间有且只有一个空格. 例如当输入字符串是 "Hello!  Game_programming  world!&q ...

  7. 微软工程师详细介绍了Windows 11原生DX12视频编码API

    导读 作为一套 Windows 平台上的多媒体解决方案,DirectX 12 在游戏和视频领域颇有建树.此前,微软已经提供了用于 GPU 加速的视频解码处理.以及运动估算的应用程序接口.而在近日的一篇 ...

  8. 《C prime plus (第五版)》 ---第11章 字符串和字符串函数---4

    字符串的例子: 1.字符串排序: 应用范围:准备花名册,建立索引以及很多情况下都会用刀字符串的排序.这个程序的主要工具就是strcmp(). 算法:读一个字符串数组,对它们进行排序并输出. #incl ...

  9. Java 11新字符串方法的基准

    在检查Java 11的新增功能时,我发现String类有几种新方法. 所以我想用旧的做事方法和使用新方法做一个微基准测试. 这些新方法是: boolean isBlank()String strip( ...

最新文章

  1. POJ 1017 Packets 贪心 模拟
  2. C 线程池(不稳定的方案)
  3. 最大整数(Noip1998连接多位数)
  4. Hadoop:The Definitive Guid 总结 Chapter 1~2 初识Hadoop、MapReduce
  5. vue基于element-ui的三级CheckBox复选框
  6. SpringMVC的工作流程
  7. C++实现各种插入排序(直接,折半,希尔)
  8. python爬取正确但不出文件_使用BeautifulSoup进行Python抓取时不显示所有行
  9. a as as big rat_超好玩!12句英语绕口令,你能一口气读完几句?
  10. 《C和指针》——宏中容易出现的错误
  11. Github | Google开源高性能机器学习研究工具Jax
  12. xmlhttp的状态码收集
  13. SpringMVC对象绑定时自定义名称对应关系
  14. 看我用ubuntu virtualbox
  15. 微信公众号采集之免费采集公众号爆文工具
  16. 管程(Moniter): 并发编程的基本心法
  17. matlab画sinc函数及其有意思的性质
  18. STM32F103+RFID-RC522模块 实现简单读卡写卡demo
  19. shell脚本批量修改文件名
  20. jmh学习笔记-State共享对象

热门文章

  1. GitHub 上数十个 NetBeans 开源项目被卷入供应链攻击
  2. 五年来,开源论坛软件MyBB共修复100多个漏洞
  3. 动态传参, 名称空间, 嵌套, gloabal, nonlocal
  4. C++ 之父即将开始直播,请就位!
  5. pythonkeywordis与 ==的差别
  6. KVM的安装和配置命令详解
  7. GDB 调试命令讲解-转
  8. link中的rel表示relation(关系),表示了当前文档与 Web 集合中其他文档的关系
  9. 1062. 最简分数(20)-PAT乙级真题
  10. 未名湖边的烦恼-蓝桥杯算法训练题-递推/递归