C ++ 여러 줄 문자열 리터럴 상수 상수를 사용할 수있는 방법이 있습니까?

C ++에서 la Perl로 여러 줄의 일반 텍스트 상수 상수를 사용할 수있는 방법이 있습니까? 어쩌면 #include파일을 파싱 하는 파싱 ​​트릭이 있습니까? 나는 하나 생각할 수 없지만 소년, 그것은 좋을 것입니다. 나는 그것이 C ++ 0x에있을 것이라는 것을 안다.



답변

글쎄요 … 가장 쉬운 방법은 인접한 문자열 리터럴이 컴파일러에 의해 연결되어 있다는 사실을 사용하는 것입니다.

const char *text =
  "This text is pretty long, but will be "
  "concatenated into just a single string. "
  "The disadvantage is that you have to quote "
  "each part, and newlines must be literal as "
  "usual.";

들여 쓰기는 따옴표 안에 없기 때문에 중요하지 않습니다.

임베드 된 개행을 피하기 위해주의를 기울이면이 작업을 수행 할 수도 있습니다. 내 첫 번째 대답처럼 그렇게하지 않으면 컴파일되지 않습니다.

const char * text2 =
  "다른 한편으로, 나는 미쳤다 \
문자 그대로 여러 줄에 걸쳐 있습니다.
각 줄을 인용하지 않아도됩니다.
함유량. 작동하지만 들여 쓰기 할 수 없습니다. ";

다시 말하지만, 각 줄의 끝에있는 백 슬래쉬는 줄 끝 바로 앞에 있어야하고 소스에서 줄 바꿈을 이스케이프해야 모든 것이 줄 바꿈이없는 것처럼 작동합니다. 백 슬래시가있는 위치의 문자열에는 줄 바꿈이 없습니다. 이 양식을 사용하면 들여 쓰기가 문자열의 일부가되어 임의의 공백으로 인해 텍스트를 들여 쓰기 할 수 있으므로 분명히 텍스트를 들여 쓸 수 없습니다.


답변

C ++ 11에는 원시 문자열 리터럴이 있습니다. 파이썬과 펄, 루비와 같은 쉘과 스크립트 언어로 된 여기 텍스트와 같습니다.

const char * vogon_poem = R"V0G0N(
             O freddled gruntbuggly thy micturations are to me
                 As plured gabbleblochits on a lurgid bee.
              Groop, I implore thee my foonting turlingdromes.
           And hooptiously drangle me with crinkly bindlewurdles,
Or I will rend thee in the gobberwarts with my blurlecruncheon, see if I don't.

                (by Prostetnic Vogon Jeltz; see p. 56/57)
)V0G0N";

문자열의 모든 공백과 들여 쓰기 및 줄 바꿈이 유지됩니다.

이들은 또한 utf-8 | 16 | 32 또는 wchar_t 일 수 있습니다 (일반적인 접두사 포함).

여기서는 이스케이프 시퀀스 V0G0N이 실제로 필요하지 않다는 점을 지적해야합니다. 그 존재는) “를 문자열 안에 넣을 수 있습니다. 다시 말하면,

                "(by Prostetnic Vogon Jeltz; see p. 56/57)"

(추가 인용 부호 참고)와 위의 문자열은 여전히 ​​정확합니다. 그렇지 않으면 나는뿐만 아니라 사용할 수 있었다

const char * vogon_poem = R"( ... )";

따옴표 안에있는 파렌은 여전히 ​​필요합니다.


답변

#define MULTILINE(...) #__VA_ARGS__
괄호 안에있는 모든 것을 소비합니다.
연속 된 공백 문자를 단일 공백으로 바꿉니다.


답변

여러 줄 문자열을 입력하는 가장 편리한 방법은 매크로를 사용하는 것입니다. 따옴표와 괄호가 균형을 이루고 ‘최상위’쉼표를 포함하지 않는 경우에만 작동합니다.

#define MULTI_LINE_STRING(a) #a
const char *text = MULTI_LINE_STRING(
  Using this trick(,) you don't need to use quotes.
  Though newlines and     multiple     white   spaces
  will be replaced by a single whitespace.
);
printf("[[%s]]\n",text);

gcc 4.6 또는 g ++ 4.6으로 컴파일하면 다음이 생성됩니다. [[Using this trick(,) you don't need to use quotes. Though newlines and multiple white spaces will be replaced by a single whitespace.]]

참고 , 그것을 괄호 나 따옴표 안에 포함 된 경우를 제외하고, 문자열에있을 수 없습니다. 작은 따옴표는 가능하지만 컴파일러 경고를 생성합니다.

편집 : 의견에서 언급했듯이 #define MULTI_LINE_STRING(...) #__VA_ARGS__의 사용을 허용합니다 ,.


답변

당신은 또한 이것을 할 수 있습니다 :

const char *longString = R""""(
This is
a very
long
string
)"""";

답변

당신은 이것을 할 수 있습니다 :

const char *text = "This is my string it is "
     "very long";

답변

1 온스의 경험은 많은 이론의 가치가 있기 때문에 다음과 같은 테스트 프로그램을 시도했습니다 MULTILINE.

#define MULTILINE(...) #__VA_ARGS__

const char *mstr[] =
{
    MULTILINE(1, 2, 3),       // "1, 2, 3"
    MULTILINE(1,2,3),         // "1,2,3"
    MULTILINE(1 , 2 , 3),     // "1 , 2 , 3"
    MULTILINE( 1 , 2 , 3 ),   // "1 , 2 , 3"
    MULTILINE((1,  2,  3)),   // "(1,  2,  3)"
    MULTILINE(1
              2
              3),             // "1 2 3"
    MULTILINE(1\n2\n3\n),     // "1\n2\n3\n"
    MULTILINE(1\n
              2\n
              3\n),           // "1\n 2\n 3\n"
    MULTILINE(1, "2" \3)      // "1, \"2\" \3"
};

이 조각을 컴파일 cpp -P -std=c++11 filename하여 재현하십시오.

트릭의 뒤에은 #__VA_ARGS____VA_ARGS__쉼표 구분 기호를 처리하지 않습니다. 따라서 문자열 화 연산자로 전달할 수 있습니다. 선행 및 후행 공백이 잘리고 단어 사이의 공백 (개행 포함)이 단일 공백으로 압축됩니다. 괄호는 균형을 이루어야합니다. 이러한 단점은 C ++ 11의 디자이너가에도 불구하고 #__VA_ARGS__원시 문자열 리터럴이 필요한 이유를 설명한다고 생각합니다 .