I'm in the middle of a project using a mysql database and spanning several languages. A problem has arisen that we need a piece of it to be in C, that reads in a query, replaces some placeholders (wrapped in '?' chars), and then runs said query.

The problem here is, C is not one of my strengths In fact, I'm almost illiterate in it. This is what I have so far, its poorly put together and doesnt even work. What it should do, is replace "?value?" with the value of repl_val.

#include <stdio.h>
#include <string.h>

int main ()
{
    char* query = "SELECT ?value? FROM Table";
    char newquery[100];
    char* repl_val = "VariableFieldName";
    
    char* pch;
    int start,end;
    int count;
    
    // get start and end indices...
    pch=strchr(query,'?');
    if (pch!=NULL)
    {
      start = pch-query;
      pch=strchr(pch+1,'?');
      end = pch-query;
    }
    // ...or return
    if(!start || !end)
    {
      return 1;
    }
    
    // copy everything before first '?', concat the replacement value
    strncpy(newquery,query,start);
    strcat(newquery,repl_val);
    
    // concat everything after the second '?', one char at a time
    for(count=end; count<strlen(query); count++)
    {
        strcat(newquery,query[count]);
    }
    
    printf("new query: %s", newquery);
    
    return 0;
}

The last for() loop wont compile, and even if i comment it out, all that prints is the repl_val surrounded by garbage. Am I just going about this all wrong?

char* query = "SELECT %s FROM Table";
    char newquery[100];
    char* repl_val = "VariableFieldName";
    sprintf( newquery, query, repl_value );

Any particular reason why you can't do this?

well, we've had to revise our design AGAIN. now, what i need to do is strip out every alphanumeric string (0-9,a-z,_) delimited by question marks, then grab an environment variable of the same name. at the same time, we want to silently pass over anything that sint a solid alphanumeric string.

ie, in the following query, i need to replace ?sql_fild1? with the environment variable ${sql_field1} , and so on for sql_field2 and sort_field. We don't want to even touch the question mark for QnAField, however.

"SELECT ?sql_field1?, ?sql_field2? FROM Table WHERE QnAField = "What is the question?" ORDER BY ?sort_field? ASC"

// should become:
"SELECT PassedField, AnotherPassedField FROM Table WHERE QnAField = "What is the question?" ORDER BY NameField ASC"

ok, ive managed to put together somthing that *finds* the placeholders (and prints them to stdout for debug purposes), im just not sure how to replace them inline with a getenv() call:

#include <stdio.h>
#include <string.h>

int do_sql_placeholders(char* source)
{
  int in_placeholder = 0; // indicate if we are inside a possible placeholder
  int pos = 0;
 
  char placeholder[256]; // to store placeholder name
  int placepos = 0;

  for (pos=0; pos < (signed int)strlen(source); pos++)
  {
    if (in_placeholder)
    {
      // if continue placeholder
      if (
          (source[pos] >= '0' && source[pos] <= '9') ||
          (source[pos] >= 'A' && source[pos] <= 'Z') ||
          (source[pos] >= 'a' && source[pos] <= 'z') ||
          source[pos] == '_'
        )
      {
        placeholder[placepos] = source[pos];
        placepos++;
      }
      // else, end place holder
      else
      {
        // valid terminated placeholder, interpolate
        if (source[pos] == '?')
        {
          placeholder[placepos] = '\0';
          /*
            instead of printing this out as a match, i need to call getenv(placeholder)
            and replace the placeholder in source with the output of getenv
          */
          printf("matched placeholder '%s' at position %d\n", placeholder, pos);
        }
        // cleanup
        in_placeholder = 0;
      
        placeholder[0] = '\0';
        placepos=0;
      }
    }
    else
    {
      if (source[pos] == '?') // entering a potential placeholder
      {
        in_placeholder = 1;
        placepos = 0;
      }
    }
  }
  return 0;
}

int main()
{
 char query[100] = "SELECT ?sql_field1?, ?sql field2? FROM Table WHERE QnAField = 'What is the question?' ORDER BY ?sort_field? ASC";

 do_sql_placeholders(query);
 printf("query: %s\n", query);

 return 0;
}
(source[pos] >= '0' && source[pos] <= '9')

Look into isdigit() in <ctype.h>. And isalpha() or isupper()+islower() for the other lines nearby.

Have you every used getenv() before? . . . if not, try reading a man page or searching google for it.

i've managed to get something working using Dave's replace function.

its shaky at best, but it does work for the time being. thanks for the advice. and i'll look into isalpha() and isdigit() as well.

This article has been dead for over six months. Start a new discussion instead.