Как разбить строковый литерал на несколько строк в C / Objective-C?

240

У меня довольно длинный 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";

Я получаю сообщение об ошибке.

Есть ли способ писать запросы в нескольких строках?

Теги:

7 ответов

437
Лучший ответ

Существует два способа разделить строки на несколько строк:

Используя \

Все строки в 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"
  • 17
    Оба они такие же, как в C и C ++. Последнее решение является предпочтительным, поскольку первое встраивает много бесполезных пробелов в программу, которые также будут передаваться на сервер БД.
  • 0
    Вы пропускаете @ в начале строки 2 в лучшем примере Objective-C.
Показать ещё 6 комментариев
77

Есть трюк, который вы можете сделать с предварительным процессором.
У этого есть потенциальные вниз стороны, что он рухнет в белом пространстве, и может быть запутанным для людей, читающих код.
Но у него есть верхняя сторона, в которой вам не нужно избегать символов цитат внутри него.

#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
    Отлично! Теперь мне нужно дать этому еще несколько сотен голосов и получить его там, где он есть ...
  • 0
    Я реагировал так же, но это не без проблем. Я просто попытался сделать heredoc таким образом с помощью специального символа Unicode и получил ошибку о том, что символы не-ASCII не допускаются за пределами литералов.
Показать ещё 1 комментарий
24

Вы также можете перейти в 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
}
  • 12
    +1 ... это рофлкоптер
  • 7
    Это никак не отвечает на вопрос ...
Показать ещё 1 комментарий
16

У меня постоянно возникает эта проблема, поэтому я сделал крошечный инструмент для преобразования текста в строку с несколькими строками Objective-C:

http://multilineobjc.herokuapp.com/

Надеюсь, это сэкономит вам некоторое время.

  • 1
    отличный инструмент! вопрос: почему вы избегаете '|'?
  • 0
    Хорошая точка зрения. Я изменил его, чтобы больше не выходить "|". Спасибо, что дали мне знать.
Показать ещё 4 комментария
13

Расширение Цитата для Objective-C:

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

NSString *sql = NSStringMultiline(
    SELECT name, age
    FROM users
    WHERE loggedin = true
);
  • 5
    Так элегантно! Это как красивый цветок с легким ароматом, нарисованный одним из голландских мастеров.
  • 3
    #define NSStringMultiline(...) @#__VA_ARGS__ тоже должен работать.
Показать ещё 5 комментариев
3

Вы также можете сделать:

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

Еще одно решение для кучи, замените файл .m на .mm так, чтобы он стал Objective-C ++ и использовал исходные литералы С++, например:

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

Исходные литералы игнорируют все до последовательности завершения, которая в случае по умолчанию представляет собой скобку-цитату. Если в какой-либо строке должна появиться последовательность кавычек-кавычек, вы можете легко указать пользовательские терминаторы, посмотрите исходные литералы С++, чтобы найти подробности об этом (это легко).

  • 0
    Я также обнаружил, что GCC добавляет необработанные строковые литералы C ++ в качестве расширения языка C: stackoverflow.com/questions/797318/…

Ещё вопросы

Сообщество Overcoder
Наверх
Меню