今天说一个C++11 引入一个小但很是有用的特性--原始字符串(raw string literal)。ios
在每一个程序中,几乎都应用到字符串字面量。但传统的字符串字面量的语法对带有特殊字符的字面量的支持不友好,它引入了一些转义字符来表示字符串中这些特殊的字符,如:正则表达式
\a 响铃(BEL) \b 退格(BS) \f 换页(FF) \n 换行(LF) \r 回车(CR) \t 水平制表(HT) \v 垂直制表(VT) \\ 反斜杠 \? 问号字符 \' 单引号字符 \" 双引号字符 \0 空字符(NULL)
这所带来的问题对于简单的字符串并不算大,但对一些特殊的应用明显不给力,好比,正则表达式:\\d{3}-\\d{8}|\\d{4}-\\d{7}
由于正则表达式大量使用了\
,而反斜杠被用来做为转义序列的开始,因此在字符串中须要使用\\
进行转义,这种语法虽然能解决问题,明显,可读性是很是差的。若应用场景再复杂点,估计不少人为了数清楚反斜杠得耗掉很多的时间。spa
若是能直接表示成\d{3}-\d{8}|\d{4}-\d{7}
,该有多好!code
C++11 终于行动了,引入了原始字符串。最基本的用法是R"(...)"
,由R
开头,双引号内包围着(...)
,实际的字符序列是小括号内的内容,小括号是字符序列的定界符。固然,左小括号和右小括号是首位对应的。blog
“原始”(raw)体如今字符串里的字符一就是一,二就是二,不会给你转义。也就是说,传统的"\n"
除了字符串结尾符,仅包含换行符,而原始字符串R"(\n)"
则包含反斜杠和字符n
,这是明显的不一样。图片
从如今来看,貌似已经很好的解决问题了,但若是字符序列里包含)"
,如R"(坐标: "(x,y)")"
,此时编译器是懵的,由于"(
对应了两个)"
。在这种状况下,咱们能够选择其余定界符,如,R"&(坐标: "(x,y)")&"
。语法以下:R"delim(...)delim"
,delim
的选取比较灵活,最长不超过16个字符,且不为小括号、空白、控制字符和反斜杠。字符串
背景中给了原始字符串在正则表达式的应用,但其应用场景不止于此,好比:编译器
R"(C:\ProgramFiles\xx\xx\xx.exe)"
string
R"({"name":"xx","age":10})"
it
在洛谷的第一道题:
这道题可使用其余技巧解答,这里仅给出使用原始字符串的解法:
#include<iostream> int main() { std::cout << R"( ******** ************ ####....#. #..###.....##.... ###.......###### ### ### ........... #...# #...# ##*####### #.#.# #.#.# ####*******###### #.#.# #.#.# ...#***.****.*###.... #...# #...# ....**********##..... ### ### ....**** *****.... #### #### ###### ###### ############################################################## #...#......#.##...#......#.##...#......#.##------------------# ###########################################------------------# #..#....#....##..#....#....##..#....#....##################### ########################################## #----------# #.....#......##.....#......##.....#......# #----------# ########################################## #----------# #.#..#....#..##.#..#....#..##.#..#....#..# #----------# ########################################## ############ )"; }
经过上面的例子,咱们也能发现原始字符串的另外两个优势:
\n
实现换行。R"(...)"
中的...
,任务就完成了,很是方便。而其余方式,都须要过多的干预拷贝的字符串,很是容易出错。请继续关注个人公众号文章