How to split a string literal across multiple lines in C / Objective-C?
CObjective CString LiteralsC 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:
-
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
-
-
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.