web-dev-qa-db-ja.com

C / Objective-Cで文字列リテラルを複数行に分割する方法

かなり長いSQLiteクエリがあります。

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";

読みやすくするために、どうしたら複数行に分割できますか?私が次のようにすれば:

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

エラーが発生しました。

複数行にクエリを書く方法はありますか?

304

文字列を複数の行に分割する方法は2つあります。

\を使う

Cのすべての行は、\を使って複数の行に分割できます。

平野C:

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

目的C:

NSString *my_string = @"Line1 \
                        Line2";

より良いアプローチ

文字列に対してのみ有効な、より良いアプローチがあります。

平野C:

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

目的C:

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

空白が多く含まれていないため、2番目の方法が優れています。ただし、SQLクエリの場合は、どちらも可能です。

注:#defineを使用すると、2つの文字列を連結するために追加の '\'を追加する必要があります。

平野C:

#define kMyString "Line 1"\
                  "Line 2"
539
Georg Schölly

プリプロセッサでできるトリックがあります。
空白を折りたたむ可能性があり、コードを読む人を混乱させる可能性があります。
しかし、引用文字をエスケープする必要がないという利点があります。

#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
);

プリプロセッサはこれを次のように変換します。

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

JSONを含む大きなリテラル文字列を含む単体テストをいくつか書いているときに、このトリックを使いました。それは私がすべての引用文字をエスケープする必要がないことを意味しました。

101
Nicholas Daley

XCode - > Preferencesの順に進んで、Indentationタブを選択し、Line Wrappingをオンにすることもできます。

そうすれば、余分なものを入力する必要がなくなり、すでに書いたものに対して機能するようになります。 :-)

迷惑なのは一つですが….

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
}
24
DenverCoder9

私はいつもこの問題を抱えているので、テキストをエスケープした複数行のObjective-C文字列に変換するための小さなツールを作りました。

http://multilineobjc.herokuapp.com/

これが時間を節約することを願っています。

20
Flaviu

Objective-Cの 見積 の考えを拡張する:

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

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

もう1つ解決策として、Objective-C++になるように.mファイルを.mmに変更し、C++の生のリテラルを次のように使用します。

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

生のリテラルは終了シーケンスまでのすべてを無視します。それはデフォルトの場合では括弧引用です。

かっこ - 引用符シーケンスを文字列のどこかに表示する必要がある場合は、次のようにカスタム区切り文字も簡単に指定できます。

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";
5
John Stephen

次のこともできます。

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

GCCはCの拡張としてC++の複数行の生の文字列リテラルを追加します

C++ 11には、次のように生の文字列リテラルがあります。 https://stackoverflow.com/a/44337236/895245

しかし、GCCはそれらをCの拡張としても追加しています。-std=gnu99の代わりに-std=c99を使用するだけです。例えば。:

main.c

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

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

コンパイルして実行します。

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

これは、たとえばCコードに複数行インラインアセンブリを挿入するのに使用できます。 GCC C++で複数行インラインアセンブリコードを記述する方法は?

今、あなたはただ横になって、それがC20XYで標準化されるのを待つ必要があります。

C++は次の場所で質問されました。 C++複数行文字列リテラル

Ubuntu 16.04、GCC 6.4.0、binutils 2.26.1でテスト済み。