かなり長い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";
エラーが発生しました。
複数行にクエリを書く方法はありますか?
文字列を複数の行に分割する方法は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"
プリプロセッサでできるトリックがあります。
空白を折りたたむ可能性があり、コードを読む人を混乱させる可能性があります。
しかし、引用文字をエスケープする必要がないという利点があります。
#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を含む大きなリテラル文字列を含む単体テストをいくつか書いているときに、このトリックを使いました。それは私がすべての引用文字をエスケープする必要がないことを意味しました。
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
}
私はいつもこの問題を抱えているので、テキストをエスケープした複数行のObjective-C文字列に変換するための小さなツールを作りました。
http://multilineobjc.herokuapp.com/
これが時間を節約することを願っています。
Objective-Cの 見積 の考えを拡張する:
#define NSStringMultiline(...) [[NSString alloc] initWithCString:#__VA_ARGS__ encoding:NSUTF8StringEncoding]
NSString *sql = NSStringMultiline(
SELECT name, age
FROM users
WHERE loggedin = true
);
もう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";
次のこともできます。
NSString * query = @"SELECT * FROM foo "
@"WHERE "
@"bar = 42 "
@"AND baz = datetime() "
@"ORDER BY fizbit ASC";
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でテスト済み。