Apakah ada cara untuk memiliki multi-line plain-text, literal konstan dalam C ++, à la Perl? Mungkin beberapa trik parsing dengan #include
file? Saya tidak bisa memikirkan satu, tapi nak, itu akan menyenangkan. Saya tahu ini akan berada di C ++ 0x.
Apakah ada cara untuk memiliki multi-line plain-text, literal konstan dalam C ++, à la Perl? Mungkin beberapa trik parsing dengan #include
file? Saya tidak bisa memikirkan satu, tapi nak, itu akan menyenangkan. Saya tahu ini akan berada di C ++ 0x.
Jawaban:
Baiklah ... Semacam. Cara termudah adalah dengan menggunakan fakta bahwa literal string yang berdekatan disatukan oleh kompiler:
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.";
Lekukan itu tidak masalah, karena tidak ada di dalam tanda kutip.
Anda juga dapat melakukan ini, selama Anda berhati-hati untuk menghindari baris baru yang disematkan. Gagal melakukannya, seperti jawaban pertama saya, tidak akan mengkompilasi:
const char * text2 = "Di sini, di sisi lain, aku sudah gila \ dan benar-benar membiarkan span span literal beberapa, tanpa repot-repot mengutip setiap baris \ kandungan. Ini berfungsi, tetapi Anda tidak dapat membuat indentasi. ";
Sekali lagi, perhatikan garis miring terbalik pada akhir setiap baris, mereka harus segera sebelum garis berakhir, mereka melarikan diri dari baris baru di sumber, sehingga semuanya bertindak seolah-olah baris baru tidak ada di sana. Anda tidak mendapatkan baris baru di string di lokasi tempat Anda mengalami garis miring terbalik. Dengan formulir ini, Anda jelas tidak dapat membuat indentasi teks karena indentasi kemudian akan menjadi bagian dari string, mengacaukannya dengan spasi acak.
Di C ++ 11 Anda memiliki literal string mentah. Semacam seperti di sini-teks dalam shell dan bahasa skrip seperti Python dan Perl dan Ruby.
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";
Semua spasi dan lekukan dan baris baru dalam string dipertahankan.
Ini juga bisa utf-8 | 16 | 32 atau wchar_t (dengan awalan biasa).
Saya harus menunjukkan bahwa urutan pelarian, V0G0N, sebenarnya tidak diperlukan di sini. Kehadirannya akan memungkinkan menempatkan) "di dalam string. Dengan kata lain, saya bisa meletakkan
"(by Prostetnic Vogon Jeltz; see p. 56/57)"
(perhatikan kutipan tambahan) dan string di atas akan tetap benar. Kalau tidak, aku bisa saja menggunakannya
const char * vogon_poem = R"( ... )";
Parens di dalam tanda kutip masih diperlukan.
#if 0
... #endif
untuk mengomentari blok kode. Sarang juga.
#define MULTILINE(...) #__VA_ARGS__
Membutuhkan segalanya di antara tanda kurung.
Mengganti sejumlah karakter spasi putih berurutan dengan satu spasi.
\n
jika Anda memerlukan baris baru
` (and hence
\ n ) is copied literally, but
"` diubah menjadi \"
. Jadi MULTILINE(1, "2" \3)
hasilkan "1, \"2\" \3"
.
Cara yang mungkin mudah untuk memasukkan string multi-line adalah dengan menggunakan makro. Ini hanya berfungsi jika tanda kutip dan tanda kurung seimbang dan tidak mengandung koma 'tingkat atas':
#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);
Dikompilasi dengan gcc 4.6 atau g ++ 4.6, ini menghasilkan: [[Using this trick(,) you don't need to use quotes. Though newlines and multiple white spaces will be replaced by a single whitespace.]]
Perhatikan bahwa ,
tidak bisa di dalam string, kecuali itu terkandung dalam tanda kurung atau kutipan. Kutipan tunggal dimungkinkan, tetapi membuat peringatan kompiler.
Sunting: Seperti yang disebutkan dalam komentar, #define MULTI_LINE_STRING(...) #__VA_ARGS__
memungkinkan penggunaan ,
.
#define MULTILINE(...) #__VA_ARGS__
jika Anda ingin string Anda mengandung koma.
\n
dan \r
), yang berguna untuk beberapa kasus dan berakibat fatal bagi yang lain.
Anda juga dapat melakukan ini:
const char *longString = R""""(
This is
a very
long
string
)"""";
char longString[] = R""""( This is a very long string )"""";
bekerja juga, untuk saya.
Karena satu ons pengalaman bernilai satu ton teori, saya mencoba program uji kecil untuk 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"
};
Kompilasi fragmen ini dengan cpp -P -std=c++11 filename
untuk mereproduksi.
Trik di belakang #__VA_ARGS__
adalah bahwa __VA_ARGS__
tidak memproses pemisah koma. Jadi, Anda bisa meneruskannya ke operator merangkai. Leading dan trailing spasi dipangkas, dan spasi (termasuk baris baru) antara kata dikompresi menjadi satu spasi. Kurung harus seimbang. Saya pikir kekurangan ini menjelaskan mengapa para perancang C ++ 11, meskipun #__VA_ARGS__
, melihat perlunya literal string mentah.
Hanya untuk menjelaskan sedikit tentang komentar @ emsr dalam jawaban @elaksasi, jika seseorang tidak cukup beruntung untuk memiliki kompiler C ++ 11 (katakanlah GCC 4.2.1), dan seseorang ingin menyematkan baris baru dalam string (baik karakter * atau string kelas), seseorang dapat menulis sesuatu seperti ini:
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.";
Sangat jelas, benar, tetapi komentar pendek @ emsr tidak langsung muncul ketika saya membaca ini pertama kali, jadi saya harus menemukan ini untuk diri saya sendiri. Mudah-mudahan, saya telah menyelamatkan orang lain beberapa menit.
// 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";
Opsi 1. Menggunakan boost library, Anda dapat mendeklarasikan string seperti di bawah ini
const boost::string_view helpText = "This is very long help text.\n"
"Also more text is here\n"
"And here\n"
// Pass help text here
setHelpText(helpText);
Opsi 2. Jika boost tidak tersedia di proyek Anda, Anda dapat menggunakan std :: string_view () di C ++ modern.