【现代C++】原始字符串-raw string literal

栏目: C++ · 发布时间: 5年前

内容简介:今天说一个C++11 引入一个小但非常有用的特性--原始字符串(raw string literal)。在每个程序中,几乎都应用到字符串字面量。但传统的字符串字面量的语法对带有特殊字符的字面量的支持不友好,它引入了一些转义字符来表示字符串中这些特殊的字符,如:如果能直接表示成

今天说一个C++11 引入一个小但非常有用的特性--原始字符串(raw string literal)。

背景

在每个程序中,几乎都应用到字符串字面量。但传统的字符串字面量的语法对带有特殊字符的字面量的支持不友好,它引入了一些转义字符来表示字符串中这些特殊的字符,如:

\a 响铃(BEL)
\b 退格(BS)
\f 换页(FF)
\n 换行(LF)
\r 回车(CR)
\t 水平制表(HT)
\v 垂直制表(VT)
\\ 反斜杠
\? 问号字符
\' 单引号字符
\" 双引号字符
\0 空字符(NULL)

这所带来的问题对于简单的字符串并不算大,但对一些特殊的应用明显不给力,比如,正则表达式:

\\d{3}-\\d{8}|\\d{4}-\\d{7}

因为正则表达式大量使用了 \ ,而反斜杠被用来作为转义序列的开始,所以在字符串中需要使用 \\ 进行转义,这种语法虽然能解决问题,明显,可读性是非常差的。若应用场景再复杂点,估计很多人为了数清楚反斜杠得耗掉不少的时间。

如果能直接表示成 \d{3}-\d{8}|\d{4}-\d{7} ,该有多好!

语法

C++11 终于行动了,引入了原始字符串。最基本的用法是 R"(...)" ,由 R 开头,双引号内包围着 (...) ,实际的字符序列是小括号内的内容,小括号是字符序列的定界符。当然,左小括号和右小括号是首位对应的。

“原始”(raw)体现在字符串里的字符一就是一,二就是二,不会给你转义。也就是说,传统的 "\n" 除了字符串结尾符,仅包含换行符,而原始字符串 R"(\n)" 则包含反斜杠和字符 n ,这是明显的不同。

从现在来看,貌似已经很好的解决问题了,但如果字符序列里包含 )" ,如 R"(坐标: "(x,y)")" ,此时编译器是懵的,因为 "( 对应了两个 )" 。在这种情况下,我们可以选择其他定界符,如, R"&(坐标: "(x,y)")&" 。语法如下:

R"delim(...)delim"delim 的选取比较灵活,最长不超过16个字符,且不为小括号、空白、控制字符和反斜杠。

应用

背景中给了原始字符串在正则表达式的应用,但其应用场景不止于此,比如:

  • Windows文件路径

R"(C:\ProgramFiles\xx\xx\xx.exe)"

  • Json字符串

R"({"name":"xx","age":10})"

例子

在洛谷的第一道题:

【现代C++】原始字符串-raw string literal

这道题可以使用其他技巧解答,这里仅给出使用原始字符串的解法:

#include<iostream>

int main() {
    std::cout << R"(                ********
               ************
               ####....#.
             #..###.....##....
             ###.......######              ###            ###
                ...........               #...#          #...#
               ##*#######                 #.#.#          #.#.#
            ####*******######             #.#.#          #.#.#
           ...#***.****.*###....          #...#          #...#
           ....**********##.....           ###            ###
           ....****    *****....
             ####        ####
           ######        ######
##############################################################
#...#......#.##...#......#.##...#......#.##------------------#
###########################################------------------#
#..#....#....##..#....#....##..#....#....#####################
##########################################    #----------#
#.....#......##.....#......##.....#......#    #----------#
##########################################    #----------#
#.#..#....#..##.#..#....#..##.#..#....#..#    #----------#
##########################################    ############ )";
}

通过上面的例子,我们也能发现原始字符串的另外两个优点:

  1. 换行能很好的保留
    其他方式都需要人工加 \n 实现换行。
  2. 方便拷贝字符串
    将拷贝的字符串直接替换 R"(...)" 中的 ... ,任务就完成了,非常方便。而其他方式,都需要过多的干预拷贝的字符串,非常容易出错。

请继续关注我的公众号文章

【现代C++】原始字符串-raw string literal


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

CSS世界

CSS世界

张鑫旭 / 人民邮电出版社 / 2017-12 / CNY 69.00

本书从前端开发人员的需求出发,以“流”为线索,从结构、内容到美化装饰等方面,全面且深入地讲解前端开发人员必须了解和掌握的大量的CSS知识点。同时,作者结合多年的从业经验,通过大量的实战案例,详尽解析CSS的相关知识与常见问题。作者还为本书开发了专门的配套网站,进行实例展示、问题答疑。 作为一本CSS深度学习的书,书中介绍大量许多前端开发人员都不知道的CSS知识点。通过阅读本书,读者会对CSS......一起来看看 《CSS世界》 这本书的介绍吧!

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具