Help us understand the problem. What is going on with this article?

C++ でも PHP のヒアドキュメント的なことができる (raw string literal)

More than 3 years have passed since last update.

概要

PHP の '' や C# の @"", python の r"" のような、エスケープ記号を省略する文字列定数の書き方は便利ですね。
C++ でも C++11 から文字列定数の仕様が追加されエスケープ記号を省略する書き方ができるようになっていました。 raw string literal と呼ぶようです。

下記リンクの (6) に当たります。
http://en.cppreference.com/w/cpp/language/string_literal

この使い方について解説します。

基本

最もミニマムな書式は

const char str[] = R"([ここに文字列定数])";

です。先頭のダブルクォートの前に 'R' をつけ、文字列定数の前後を '('')' で囲みます。
例えば Windows のパス文字列 C:\path\to\folder\file.txt のようなものを const char に代入したいと思ったとき、従来は

const char str[] = "C:\\path\\to\\folder\\file.txt";

と書いていたのを、

const char str[] = R"(C:\path\to\folder\file.txt)";

のように代入できます。

文字列定数の中ではダブルクォート '"' もエスケープなしで使用できます。

#include <iostream>

int main(void){
    std::cout << R"("Hello, World")" << std::endl;
}
出力
"Hello, World"

便利ですねー。

特別な場合

上記の仕様だけでほとんどの場合問題ありませんが、以下のような場合には困ります。

#include <iostream>

int main(void){
    // コンパイルエラー!
    std::cout << R"("Hello, World(1)")" << std::endl;
}

この例では、 "Hello, World(1 までが raw string literal と解釈されてしまうためコンパイルエラーとなります。文字列定数中に )" を含んでいてはいけないわけです。
しかしこのようなケースに対処する仕様がしっかり用意されています。

#include <iostream>

int main(void){
    // OK!
    std::cout << R"#("Hello, World(1)")#" << std::endl;
}

のように、 R"( の間に任意の文字列(*)を付け足して開始・終了パターンを変更することができます。

(*) (, ), \, を除いた英数字。最大 16 字まで

他の書式との組み合わせ

raw string literal は他の文字列定数書式と組み合わせることができます。

  • R("...")const char[ ].
  • LR("...)"const wchar_t[ ].
  • u8R("...)"const char[ ] (UTF-8).
  • uR("...)"const char16_t[ ] (UTF-16).
  • UR("...)"const char32_t[ ] (UTF-32).

下例では UTF-8 形式の文字列定数をコンソール出力しています。

main.cpp
#include <iostream>
using namespace std;

int main(void){

    cout << u8R"##(<!DOCTYPE html>
<html lang="ja">
    <head>
        <meta charset="UTF-8">
        <title>Hello</title>
    </head>
    <body>
        Hello, World!!!
    </body>
</html>
)##";
}
出力
<!DOCTYPE html>
<html lang="ja">
    <head>
        <meta charset="UTF-8">
        <title>Hello</title>
    </head>
    <body>
        Hello, World!!!
    </body>
</html>
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away