-3

I'm writing some C code using the MySQL api to create databases, insert, update etc. I'm having a little trouble finding the cleanest/correct way to build the queries since the MySQL syntax can be tricky to put in a c string, for example, I'd like a query to look like this for readability:

   strcpy(query, "CREATE TABLE Users (
                  userID INT NOT NULL AUTO_INCREMENT, PRIMARY KEY (userID),
                  email  VARCHAR(31) NOT NULL,
                  timeEntered   TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
                  address       VARCHAR(31) NOT NULL,
                  index (email))
                 ");

then of course I'd be running the query with something like

   /* send SQL query */
   if (mysql_query(conn, query)) {
      fprintf(stderr, "%s\n", mysql_error(conn));
      exit(1);
   } else { printf("table created\n"); }

however the compiler complains about expected ‘)’ and missing terminating " etc. Whats the best solution?

nak3c
  • 439
  • 1
  • 6
  • 18

3 Answers3

3

For readability I suggest you use C89's string concatenation feature:

strcpy(query, "CREATE TABLE Users ("
              "userID INT NOT NULL AUTO_INCREMENT, PRIMARY KEY (userID),"
              "email  VARCHAR(31) NOT NULL,"
              "timeEntered   TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,"
              "address       VARCHAR(31) NOT NULL,"
              "index (email))"
);

Simply use a sequence of string literals separated by as much white-space as you need for readability.

In the olden days of K&R C there was only the backslash-newline way of doing this:

puts("A very\
 long string\
 literal spanning\
 several lines");
Jens
  • 69,818
  • 15
  • 125
  • 179
1

C string literals cannot contains line breaks. You can do this though:

   strcpy(query, "CREATE TABLE Users ("
                 "userID INT NOT NULL AUTO_INCREMENT, PRIMARY KEY (userID), "
                 "email  VARCHAR(31) NOT NULL, "
                 "timeEntered   TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, "
                 "address       VARCHAR(31) NOT NULL, "
                 "index (email))");

This creates a single string literal from the adjacent string literals.

Emil Laine
  • 41,598
  • 9
  • 101
  • 157
  • Added detail "cannot contains line breaks" --> string literal can contain any member of the source character set except the double-quote ", backslash \, or new-line character " – chux - Reinstate Monica Jan 01 '17 at 21:36
1

C++ compilers don't generally support multiline string constants, for C I think it probably differs from compiler to compiler and level of standard they meet.

It's safer to split it to several strings without any separator, this is understood by any compiler:

strcpy(query, "CREATE TABLE Users ("
             " userID INT NOT NULL AUTO_INCREMENT, PRIMARY KEY (userID),"
             " email  VARCHAR(31) NOT NULL,"
             " timeEntered   TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,"
             " address       VARCHAR(31) NOT NULL,"
             " index (email))"
             );
Zbynek Vyskovsky - kvr000
  • 18,186
  • 3
  • 35
  • 43