C ++에서 la Perl로 여러 줄의 일반 텍스트 상수 상수를 사용할 수있는 방법이 있습니까? 어쩌면 #include
파일을 파싱 하는 파싱 트릭이 있습니까? 나는 하나 생각할 수 없지만 소년, 그것은 좋을 것입니다. 나는 그것이 C ++ 0x에있을 것이라는 것을 안다.
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"( ... )";
따옴표 안에있는 파렌은 여전히 필요합니다.
#if 0
… #endif
를 사용하십시오 . 둥지도.
#define MULTILINE(...) #__VA_ARGS__
괄호 안에있는 모든 것을 소비합니다.
연속 된 공백 문자를 단일 공백으로 바꿉니다.
\n
바꿈이 필요한 경우 추가 할 수 있습니다
` (and hence
\ n을 ) is copied literally, but
''로 변환 \"
그래서의. MULTILINE(1, "2" \3)
금리 "1, \"2\" \3"
.
여러 줄 문자열을 입력하는 가장 편리한 방법은 매크로를 사용하는 것입니다. 따옴표와 괄호가 균형을 이루고 '최상위'쉼표를 포함하지 않는 경우에만 작동합니다.
#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__
의 사용을 허용합니다 ,
.
#define MULTILINE(...) #__VA_ARGS__
문자열에 쉼표를 포함 시키려면 사용할 수 있습니다 .
\n
및 \r
)를 제거하여 일부 경우에는 유용하고 다른 경우에는 치명적입니다.
당신은 또한 이것을 할 수 있습니다 :
const char *longString = R""""(
This is
a very
long
string
)"""";
char longString[] = R""""( This is a very long string )"""";
작동합니다.
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__
원시 문자열 리터럴이 필요한 이유를 설명한다고 생각합니다 .
C ++ 11 컴파일러 (GCC 4.2.1)를 가질만큼 운이 좋지 않고 문자열에 개행을 포함시키려는 경우 @unwind의 답변에서 @emsr의 의견에 대해 조금 설명하기 만하면됩니다 (char * 또는 클래스 문자열), 다음과 같이 작성할 수 있습니다.
const char *text =
"This text is pretty long, but will be\n"
"concatenated into just a single string.\n"
"The disadvantage is that you have to quote\n"
"each part, and newlines must be literal as\n"
"usual.";
매우 명백하고 사실이지만, 처음 읽었을 때 @emsr의 짧은 의견이 나에게 튀어 나오지 않았으므로 직접 발견해야했습니다. 잘만되면, 나는 몇 분 동안 다른 사람을 구했습니다.
// C++11.
std::string index_html=R"html(
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>VIPSDK MONITOR</title>
<meta http-equiv="refresh" content="10">
</head>
<style type="text/css">
</style>
</html>
)html";