How to split a string literal across multiple lines in C / Objective-C?

CObjective CString Literals

C Problem Overview


I have a pretty long sqlite query:

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

How can I break it in a number of lines to make it easier to read? If I do the following:

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

I am getting an error.

Is there a way to write queries in multiple lines?

C Solutions


Solution 1 - C

There are two ways to split strings over multiple lines:

  1. Each string on its own line. Works only with strings:

    • Plain C:

      char *my_string = "Line 1 "
                        "Line 2";
      
    • Objective-C:

      NSString *my_string = @"Line1 "
                             "Line2";    // the second @ is optional
      
  2. Using \ - can be used for any expression:

    • Plain C:

      char *my_string = "Line 1 \
                         Line 2";
      
    • Objective-C:

      NSString *my_string = @"Line1 \
                              Line2";
      

The first approach is better, because there isn't a lot of whitespace included. For a SQL query however, both are possible.

NOTE: With a #define, you have to add an extra \ to concatenate the two strings:

Plain C:

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

Solution 2 - C

There's a trick you can do with the pre-processor.
It has the potential down sides that it will collapse white-space, and could be confusing for people reading the code.
But, it has the up side that you don't need to escape quote characters inside it.

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

the preprocessor turns this into:

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

I've used this trick when I was writing some unit tests that had large literal strings containing JSON. It meant that I didn't have to escape every quote character ".

Solution 3 - C

You could also go into XCode -> Preferences, select the Indentation tab, and turn on Line Wrapping.

That way, you won't have to type anything extra, and it will work for the stuff you already wrote. :-)

One annoying thing though is...

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
}

Solution 4 - C

I am having this problem all the time, so I made a tiny tool to convert text to an escaped multi-line Objective-C string:

http://multilineobjc.herokuapp.com/

Hope this saves you some time.

Solution 5 - C

Extending the Quote idea for Objective-C:

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

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

Solution 6 - C

One more solution for the pile, change your .m file to .mm so that it becomes Objective-C++ and use C++ raw literals, like this:

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

Raw literals ignore everything until the termination sequence, which in the default case is parenthesis-quote.

If the parenthesis-quote sequence has to appear in the string somewhere, you can easily specify a custom delimiter too, like this:

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

Solution 7 - C

GCC adds C++ multiline raw string literals as a C extension

C++11 has raw string literals as mentioned at: https://stackoverflow.com/a/44337236/895245

However, GCC also adds them as a C extension, you just have to use -std=gnu99 instead of -std=c99. E.g.:

main.c

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

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

Compile and run:

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

This can be used for example to insert multiline inline assembly into C code: https://stackoverflow.com/questions/3666013/how-to-write-multiline-inline-assembly-code-in-gcc-c/54575948#54575948

Now you just have to lay back, and wait for it to be standardized on C20XY.

C++ was asked at: https://stackoverflow.com/questions/1135841/c-multiline-string-literal

Tested on Ubuntu 16.04, GCC 6.4.0, binutils 2.26.1.

Solution 8 - C

You can also do:

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

Solution 9 - C

An alternative is to use any tool for removing line breaks. Write your string using any text editor, once you finished, paste your text here and copy it again in xcode.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionIlya SuzdalnitskiView Question on Stackoverflow
Solution 1 - CGeorg SchöllyView Answer on Stackoverflow
Solution 2 - CNicholas Daley-OkoyeView Answer on Stackoverflow
Solution 3 - CDenverCoder9View Answer on Stackoverflow
Solution 4 - CFlaviuView Answer on Stackoverflow
Solution 5 - CBerikView Answer on Stackoverflow
Solution 6 - CJohn StephenView Answer on Stackoverflow
Solution 7 - CCiro Santilli Путлер Капут 六四事View Answer on Stackoverflow
Solution 8 - CDave DeLongView Answer on Stackoverflow
Solution 9 - COUBERGHOUZ MOHAMEDView Answer on Stackoverflow