今天說一個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"(...)"
中的...
,任務就完成了,很是方便。而其餘方式,都須要過多的干預拷貝的字符串,很是容易出錯。請繼續關注個人公衆號文章