385

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?

8 Answers 8

664

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"
Sign up to request clarification or add additional context in comments.

9 Comments

Both of these are the same as in and C and C++. The latter solution is preferred because former one embeds a lot of useless white space into the program which will also be transmitted to the DB server.
You're missing an @ at the start of line 2 in the better Objective-C example.
Another advantage of the better approach is, that you can put // comments after each line.
Does the second approach insert either \n or \r\n between the lines?
@Charles: No, the strings are simply concatenated.
|
147

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 \".

6 Comments

Perfect! Now I just need to give this a few more hundred upvotes, and get it where it belongs...
I was reacting the same way, but this is not without issues. I just tried doing a heredoc this way with a special Unicode character and got an error about non-ASCII characters not being allowed outside of literals.
+1 but for the record I´m having trouble with the compiler (MSVC) or editor (QtCreator) not (re)compiling the expression as it should on change. It is like change is not detected... Hitting Rebuild instead of Build does the trick.
Thank you for this Chicken Nugget of information. It does exactly what I needed to do without all the extra garbage.
This unfortunately doesn't work if you have literal quotation marks in the string. Well, it kind of works, in that it generates a warning. But my codebase is -Werror...
|
25

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
}

1 Comment

@YoYoYonnY I agree, but I also appreciate it. It strikes me that this comment would not have been truly possible as a comment, hence the use of the answer format. This seems like a limitation of S/O, that you can't write particularly rich comments (as far as I am aware).
20

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

5 Comments

#define NSStringMultiline(...) @#__VA_ARGS__ should work too.
For mutable strings: #define NSStringMultiline(...) [[NSMutableString alloc] initWithCString:#__VA_ARGS__ encoding:NSUTF8StringEncoding]
For me, the resulting string does not have new lines.
Escaped newlines are captured correctly (which is not nearly so convenient or nice).
@rimsky, And I think that #define NSStringMultiline(...) [@#__VA_ARGS__ mutableCopy] also works for mutable strings.
10

Another solution, 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";

1 Comment

I've also found that GCC adds C++ raw string literals as an extension to the C language: stackoverflow.com/questions/797318/…
7

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: How to write multiline inline assembly code in GCC C++?

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

C++ was asked at: C++ multiline string literal

Tested on Ubuntu 16.04, GCC 6.4.0, binutils 2.26.1.

Comments

4

You can also do:

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

Comments

-1

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.

1 Comment

No really a long term solution. What if you have to change it again later. Get's annoying fast, better to use the multi line techniqies already mentioned and format it directly in the file.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.