Bir dizgi değişmezini C / Objective-C'de birden çok satıra bölmek nasıl?


321

Oldukça uzun sqlite sorgu var:

const char *sql_query = "SELECT statuses.word_id FROM lang1_words, statuses WHERE statuses.word_id = lang1_words.word_id ORDER BY lang1_words.word ASC";

Okumayı kolaylaştırmak için birkaç satıra nasıl bölebilirim? Aşağıdakileri yaparsam:

const char *sql_query = "SELECT word_id
                        FROM table1, table2
                        WHERE table2.word_id = table1.word_id
                        ORDER BY table1.word ASC";

Bir hata alıyorum.

Birden çok satıra sorgu yazmanın bir yolu var mı?

Yanıtlar:


569

Dizeleri birden çok satıra bölmenin iki yolu vardır:

\

C'deki tüm satırlar \ kullanılarak birden çok satıra bölünebilir.

Düz C:

char *my_string = "Line 1 \
                   Line 2";

Objective-C:

NSString *my_string = @"Line1 \
                        Line2";

Daha iyi yaklaşım

Sadece teller için çalışan daha iyi bir yaklaşım var.

Düz C:

char *my_string = "Line 1 "
                  "Line 2";

Objective-C:

NSString *my_string = @"Line1 "
                       "Line2";    // the second @ is optional

İkinci yaklaşım daha iyidir, çünkü çok fazla boşluk dahil değildir. Ancak bir SQL sorgusu için her ikisi de mümkündür.

NOT: #define ile, iki dizeyi birleştirmek için fazladan bir \ \ eklemeniz gerekir:

Düz C:

#define kMyString "Line 1"\
                  "Line 2"

22
Bunların her ikisi de in ve C ve C ++ ile aynıdır. İkinci çözüm tercih edilir, çünkü eski çözüm programa DB sunucusuna da iletilecek çok fazla boş alan bırakır.
Alnitak

Daha iyi Objective-C örneğinde 2. satırın başında bir @ eksik.
Lawrence Johnston

İkincisinin opsiyonelliğini belgeleyen bir spesifikasyonla bağlantınız var @mı?
Heath Borders

@HeathBorders: Tam burada değil, ama cevabı yazdığımda baktım.
Georg Schölly

10
Daha iyi yaklaşımın bir diğer avantajı, her satırdan sonra // yorum yazabilmenizdir.
fishin2

110

Ön işlemciyle yapabileceğiniz bir numara var.
Beyaz boşluğu daraltma potansiyeli vardır ve kodu okuyan insanlar için kafa karıştırıcı olabilir.
Ancak, içindeki alıntı karakterlerden kaçmanız gerekmeyen yukarı tarafı vardır.

#define QUOTE(...) #__VA_ARGS__
const char *sql_query = QUOTE(
    SELECT word_id
    FROM table1, table2
    WHERE table2.word_id = table1.word_id
    ORDER BY table1.word ASC
);

önişlemci bunu şuna dönüştürür:

const char *sql_query = "SELECT word_id FROM table1, table2 WHERE table2.word_id = table1.word_id ORDER BY table1.word ASC";

JSON içeren büyük değişmez dizeleri olan bazı birim testleri yazarken bu hileyi kullandım. Bu, her alıntı karakterinden kaçmak zorunda olmadığım anlamına geliyordu \ ".


5
Mükemmel! Şimdi sadece bu birkaç yüz upvotes vermek ve ait olduğu yere almak gerekir ...
Mike

Ben de aynı şekilde tepki veriyordum, ama bu hiç sorun değil. Özel bir Unicode karakteri ile bu şekilde bir heredoc yapmayı denedim ve ASCII olmayan karakterlerin değişmezlerin dışında izin verilmemesiyle ilgili bir hata aldım.
philipkd

+1 ama kayıt için ben derleyici (MSVC) veya editör (QtCreator) ile sorun yaşıyorum ben ifade gerektiği gibi ifade derleme (yeniden) değil. Değişim algılanmaz gibi ... Build yerine Rebuild'e basmak hile yapar.
Andreas

Bu Tavuk Nugget bilgi için teşekkür ederim. Tüm ekstra çöp olmadan yapmam gereken şeyi yapıyor.
FishGuy876

Dizede gerçek tırnak işaretleri varsa bu maalesef çalışmaz. Bir çeşit uyarı oluşturması açısından bir çeşit işe yarıyor. Ama kod
tabanım -Kahta

24

Ayrıca XCode -> Tercihler'e gidebilir, Girinti sekmesini seçebilir ve Satır Sarmayı açabilirsiniz.

Bu şekilde, fazladan bir şey yazmak zorunda kalmazsınız ve zaten yazdığınız şeyler için işe yarayacaktır. :-)

Rahatsız edici bir şey olsa ...

if (you're long on indentation
    && short on windows) {
            then your code will
                end up squished
                     against th
                         e side
                             li
                              k
                              e

                              t
                              h
                              i
                              s
}

2
@YoYoYonnY Kabul ediyorum, ama ben de takdir ediyorum. Bu yorumun bir yorum olarak gerçekten mümkün olmayacağına, dolayısıyla cevap formatının kullanılmasına dikkat çekiyor. Bu, özellikle zengin yorumlar yazamayacağınız bir S / O sınırlaması gibi görünüyor (bildiğim kadarıyla).
Max von Hippel

24

Ben her zaman bu sorunu yaşıyorum, bu yüzden metin kaçan çok satırlı Objective-C dizeye dönüştürmek için küçük bir araç yaptım:

http://multilineobjc.herokuapp.com/

Umarım bu size biraz zaman kazandırır.


1
harika bir araç! soru: neden '|' den kaçıyorsunuz?
justadreamer

İyi bir nokta. Artık "|" 'dan kaçmayacak şekilde değiştirdim. Bilmeme izin verdiğin için teşekkürler.
Flaviu

Aynı fikrim vardı. Keşke bunu ilk görseydim. Benim aracım
Nate Flink

1
Teşekkürler, çok zaman kazandım!
djskinner

Clang Formatını kullanmayı deneyin (en sevdiğiniz editörlerle bütünleşir): clang.llvm.org/docs/ClangFormat.html
Ahmed Fasih

18

Objective-C için Alıntı fikrini genişletmek :

#define NSStringMultiline(...) [[NSString alloc] initWithCString:#__VA_ARGS__ encoding:NSUTF8StringEncoding]

NSString *sql = NSStringMultiline(
    SELECT name, age
    FROM users
    WHERE loggedin = true
);

3
#define NSStringMultiline(...) @#__VA_ARGS__çalışmalı.
Nicholas Daley

#define NSStringMultiline(...) [[NSMutableString alloc] initWithCString:#__VA_ARGS__ encoding:NSUTF8StringEncoding]
Değişken

Benim için, ortaya çıkan dizenin yeni satırları yok.
rimsky

Kaçan yeni satırlar doğru şekilde yakalanır (neredeyse çok uygun veya hoş değildir).
rimsky

@rimsky, Ve bence bu #define NSStringMultiline(...) [@#__VA_ARGS__ mutableCopy]değişebilir teller için de işe yarıyor.
Iulian Onofrei

5

Yığın için bir çözüm daha. Objektif-C ++ olacak şekilde .m dosyanızı .mm olarak değiştirin ve aşağıdaki gibi C ++ ham değişmezlerini kullanın:

const char *sql_query = R"(SELECT word_id
                           FROM table1, table2
                           WHERE table2.word_id = table1.word_id
                           ORDER BY table1.word ASC)";

Ham değişmezler, varsayılan durumda parantez-alıntı olan sonlandırma sırasına kadar her şeyi yok sayar.

Parantez-alıntı sırasının dizede bir yerde görünmesi gerekiyorsa, aşağıdaki gibi kolayca özel bir sınırlayıcı da belirtebilirsiniz:

const char *sql_query = R"T3RM!N8(
                                  SELECT word_id
                                  FROM table1, table2
                                  WHERE table2.word_id = table1.word_id
                                  ORDER BY table1.word ASC
                         )T3RM!N8";

Ayrıca, GCC'nin C diline bir uzantı olarak C ++ ham dize değişmezlerini eklediğini de buldum: stackoverflow.com/questions/797318/…
Ciro Santilli: 冠状 病 六四 事件 法轮功

3

Ayrıca şunları da yapabilirsiniz:

NSString * query = @"SELECT * FROM foo "
                   @"WHERE "
                     @"bar = 42 "
                     @"AND baz = datetime() "
                   @"ORDER BY fizbit ASC";

2

GCC, C uzantısı olarak C ++ çok satırlı ham dize değişmezlerini ekler

C ++ 11'in belirtildiği gibi ham dize değişmezleri vardır: https://stackoverflow.com/a/44337236/895245

Ancak, GCC bunları bir C uzantısı olarak ekler, -std=gnu99bunun yerine kullanmanız yeterlidir -std=c99. Örneğin:

main.c

#include <assert.h>
#include <string.h>

int main(void) {
    assert(strcmp(R"(
a
b
)", "\na\nb\n") == 0);
}

Derleyin ve çalıştırın:

gcc -o main -pedantic -std=gnu99 -Wall -Wextra main.c
./main

Bu, örneğin C koduna çok satırlı satır içi montaj eklemek için kullanılabilir: GCC C ++ 'da çok satırlı satır içi montaj kodu nasıl yazılır?

Şimdi sadece uzanmanız ve C20XY'de standartlaştırılmasını beklemeniz gerekiyor.

C ++ istendi: C ++ çok satırlı dize hazır bilgisi

Ubuntu 16.04, GCC 6.4.0, binutils 2.26.1 üzerinde test edilmiştir.


0

Alternatif olarak satır sonlarını kaldırmak için herhangi bir araç kullanılabilir. Dizenizi herhangi bir metin düzenleyicisi kullanarak yazın, işiniz bittiğinde metninizi buraya yapıştırın ve tekrar xcode içine kopyalayın.


1
Gerçekten uzun vadeli bir çözüm yok. Daha sonra tekrar değiştirmek zorunda kalırsanız. Daha önce bahsedilen çok satırlı teknikleri kullanmak ve doğrudan dosyada biçimlendirmek için can sıkıcı hızlı, daha iyi olsun.
Schwarzie2478
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.