Как разбить строковый литерал на несколько строк в 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";
Я получаю ошибку.
Есть ли способ писать запросы в несколько строк?
Ответы
Ответ 1
Существует два способа разделить строки на несколько строк:
Используя \
Все строки в C можно разбить на несколько строк, используя \.
Обычная C:
char *my_string = "Line 1 \
Line 2";
Objective-C:
NSString *my_string = @"Line1 \
Line2";
Лучший подход
Там лучший подход, который работает только для строк.
Обычная C:
char *my_string = "Line 1 "
"Line 2";
Objective-C:
NSString *my_string = @"Line1 "
"Line2"; // the second @ is optional
Второй подход лучше, потому что в него не включено много пробелов. Однако для SQL-запроса возможны оба варианта.
ПРИМЕЧАНИЕ. С#define вам нужно добавить дополнительный '\', чтобы объединить две строки:
Обычная C:
#define kMyString "Line 1"\
"Line 2"
Ответ 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. Это означало, что мне не пришлось скрывать каждого символа кавычки.
Ответ 3
Вы также можете перейти в XCode → Настройки, выбрать вкладку "Отступ" и включить "Линейная упаковка".
Таким образом, вам не придется вводить ничего лишнего, и он будет работать для того, что вы уже писали.: -)
Одна досадная вещь, хотя...
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
}
Ответ 4
У меня постоянно возникает эта проблема, поэтому я сделал крошечный инструмент для преобразования текста в строку с несколькими строками Objective-C:
http://multilineobjc.herokuapp.com/
Надеюсь, это сэкономит вам некоторое время.
Ответ 5
Расширение Цитата для Objective-C:
#define NSStringMultiline(...) [[NSString alloc] initWithCString:#__VA_ARGS__ encoding:NSUTF8StringEncoding]
NSString *sql = NSStringMultiline(
SELECT name, age
FROM users
WHERE loggedin = true
);
Ответ 6
Еще одно решение для кучи: измените файл .m на .mm, чтобы он стал Objective- C++, и используйте необработанные литералы 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";
Ответ 7
Вы также можете сделать:
NSString * query = @"SELECT * FROM foo "
@"WHERE "
@"bar = 42 "
@"AND baz = datetime() "
@"ORDER BY fizbit ASC";
Ответ 8
GCC добавляет C++ многострочные необработанные строковые литералы как расширение C
C++ 11 имеет необработанные строковые литералы, как указано на: fooobar.com/info/26730/...
Однако 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.