C ++, à la Perl'de çok satırlı düz metin, sabit değişmez değerler kullanmanın bir yolu var mı? Belki #include
bir dosya ing ile bazı ayrıştırma hilesi ? Birini düşünemiyorum, ama oğlum, bu iyi olurdu. C ++ 0x olacağını biliyorum.
C ++, à la Perl'de çok satırlı düz metin, sabit değişmez değerler kullanmanın bir yolu var mı? Belki #include
bir dosya ing ile bazı ayrıştırma hilesi ? Birini düşünemiyorum, ama oğlum, bu iyi olurdu. C ++ 0x olacağını biliyorum.
Yanıtlar:
İyi sıralama. En kolayı, sadece bitişik dize değişmezlerinin derleyici tarafından birleştirildiği gerçeğini kullanmaktır:
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.";
Girintinin önemi yoktur, çünkü tırnak içinde değildir.
Katıştırılmış yeni satırdan kaçmaya özen gösterdiğiniz sürece bunu da yapabilirsiniz. Bunun yapılmaması, ilk cevabımın yaptığı gibi derlenmeyecek:
const char * text2 = "Öte yandan, ben çıldırdım \ ve kelimenin tam anlamıyla birkaç satıra izin ver, \ her satırın alıntılar ile uğraşmadan \ içeriği. Bu işe yarıyor, ancak girintilemezsiniz. ";
Yine, her satırın sonundaki ters eğik çizgilere dikkat edin, satır bitmeden hemen önce olmalılar, kaynaktaki yeni satırdan kaçıyorlar, böylece her şey yeni satır orada yokmuş gibi davranıyor. Ters eğik çizgi yaptığınız konumlarda dizede yeni satırlar almazsınız. Bu formla metni açıkça girintilemezsiniz çünkü girinti daha sonra dizenin bir parçası haline gelir ve rastgele boşluklarla karışır.
C ++ 11'de ham dize değişmezleri var. Python ve Perl ve Ruby gibi kabuklarda ve senaryo dillerinde buradaki metin gibi.
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";
Dizedeki tüm boşluklar ve girinti ve satırsonları korunur.
Bunlar ayrıca utf-8 | 16 | 32 veya wchar_t (normal öneklerle birlikte) olabilir.
Burada kaçış dizisi olan V0G0N'nin aslında gerekli olmadığını belirtmeliyim. Onun varlığı dizginin içine koymak) izin verir. Başka bir deyişle, ben koymak olabilir
"(by Prostetnic Vogon Jeltz; see p. 56/57)"
(ekstra alıntılara dikkat edin) ve yukarıdaki dize yine de doğru olur. Aksi takdirde,
const char * vogon_poem = R"( ... )";
Tırnakların içindeki parenler hala gereklidir.
#if 0
… tuşunu kullanın #endif
. Yuvalar da.
#define MULTILINE(...) #__VA_ARGS__
Parantezler arasındaki her şeyi tüketir.
İstediğiniz sayıda ardışık boşluk karakteri tek bir boşlukla değiştirir.
\n
satırlara ihtiyacınız varsa ekleyebilirsiniz
` (and hence
\ n ) is copied literally, but
"` dönüştürülür \"
Yani. MULTILINE(1, "2" \3)
Verimleri "1, \"2\" \3"
.
Çok satırlı dizeler girmenin muhtemelen uygun bir yolu makroları kullanmaktır. Bu yalnızca tırnak işaretleri ve parantezler dengeliyse çalışır ve 'üst düzey' virgül içermez:
#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 veya g ++ 4.6 ile derlendiğinde, bu aşağıdakileri üretir: [[Using this trick(,) you don't need to use quotes. Though newlines and multiple white spaces will be replaced by a single whitespace.]]
Unutmayın ki ,
Parantez veya tırnak içinde bulunmadıkça, dizenin içinde olamayacağını . Tek tırnak işaretleri mümkündür, ancak derleyici uyarıları oluşturur.
Düzenleme: Yorumlarda belirtildiği gibi #define MULTI_LINE_STRING(...) #__VA_ARGS__
, kullanımını sağlar ,
.
#define MULTILINE(...) #__VA_ARGS__
Dizenizin virgül içermesini istiyorsanız kullanabilirsiniz .
\n
ve dahil \r
) çıkaracaktır .
Bunu da yapabilirsiniz:
const char *longString = R""""(
This is
a very
long
string
)"""";
char longString[] = R""""( This is a very long string )"""";
benim için de çalışıyor.
Bir ons deneyim bir ton teoriye değer olduğundan, aşağıdakiler için küçük bir test programı denedim 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
Çoğaltmak için bu parçayı derleyin .
Hüner arkasında #__VA_ARGS__
olduğunu __VA_ARGS__
virgül ayırıcı işlemez. Böylece dizgi operatörüne iletebilirsiniz. Öndeki ve sondaki boşluklar kesilir ve sözcükler arasındaki boşluklar (satır satırları dahil) tek bir alana sıkıştırılır. Parantezlerin dengelenmesi gerekir. Bu eksikliklerin, C ++ 11 tasarımcılarının neden #__VA_ARGS__
ham dize değişmezlerine ihtiyaç duyduklarını açıkladığını düşünüyorum.
Sadece @ emsr'in @ unwind'ın cevabındaki açıklamasını biraz açıklamak için, biri bir C ++ 11 derleyicisine (GCC 4.2.1 diyelim) sahip olmak için yeterince şanslı değilse ve yeni satırları dizeye gömmek istiyorsa (char * veya sınıf dizesi), böyle bir şey yazabilirsiniz:
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.";
Çok açık, doğru, ama @ emsr'in kısa yorumu bunu ilk kez okuduğumda bana atlamadı, bu yüzden bunu kendim keşfetmek zorunda kaldım. İnşallah birkaç dakika daha birini kurtardım.
// 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";
Seçenek 1. Destek kitaplığını kullanarak dizeyi aşağıdaki gibi bildirebilirsiniz
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);
Seçenek 2. Projenizde destek yoksa, modern C ++ 'da std :: string_view () kullanabilirsiniz.