¿Cómo dividir un literal de cadena en múltiples líneas en C / Objective-C?

Tengo una consulta sqlite bastante larga:

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

¿Cómo puedo dividirlo en varias líneas para que sea más fácil de leer? Si hago lo siguiente:

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

Me está dando un error.

¿Hay alguna forma de escribir consultas en múltiples líneas?

Hay dos formas de dividir cadenas en múltiples líneas:

Utilizando \

Todas las líneas en C se pueden dividir en varias líneas con \.

Llanura C:

 char *my_string = "Line 1 \ Line 2"; 

C objective:

 NSString *my_string = @"Line1 \ Line2"; 

Mejor enfoque

Hay un mejor enfoque que funciona solo para cadenas.

Llanura C:

 char *my_string = "Line 1 " "Line 2"; 

C objective:

 NSString *my_string = @"Line1 " "Line2"; // the second @ is optional 

El segundo enfoque es mejor, porque no hay mucho espacio en blanco incluido. Sin embargo, para una consulta SQL, ambos son posibles.

NOTA: Con un #define, debe agregar un ‘\’ adicional para concatenar las dos cadenas:

Llanura C:

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

Hay un truco que puedes hacer con el pre-procesador.
Tiene la desventaja potencial de que colapsará el espacio en blanco, y podría ser confuso para las personas que leen el código.
Pero tiene la ventaja de que no necesita escapar caracteres de comillas dentro de él.

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

el preprocesador lo convierte en:

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

He usado este truco cuando escribía algunas pruebas unitarias que tenían cadenas literales grandes que contenían JSON. Significaba que no tenía que escapar de cada personaje de cita \ “.

También puede ir a XCode -> Preferencias, seleccionar la pestaña Sangría y activar Enlazado de línea.

De esta forma, no tendrá que escribir nada extra, y funcionará para las cosas que ya escribió. 🙂

Una cosa molesta es …

 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 } 

Estoy teniendo este problema todo el tiempo, así que creé una pequeña herramienta para convertir texto a una cadena Objective-C multilínea escapada:

http://multilineobjc.herokuapp.com/

Espero que esto te ahorre algo de tiempo.

Extendiendo la idea de Cita para Objective-C:

 #define NSStringMultiline(...) [[NSString alloc] initWithCString:#__VA_ARGS__ encoding:NSUTF8StringEncoding] NSString *sql = NSStringMultiline( SELECT name, age FROM users WHERE loggedin = true ); 

Una solución más para el montón, cambie su archivo .m a .mm para que se convierta en Objective-C ++ y use literales crudos C ++, como este:

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

Los literales crudos ignoran todo hasta la secuencia de finalización, que en el caso predeterminado es paréntesis-cita.

Si la secuencia de comillas entre paréntesis debe aparecer en alguna cadena, también puede especificar fácilmente un delimitador personalizado, como este:

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

También puedes hacer:

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