Question

I am using PostgreSql C library libpq, and I can fetch values from the PGresult pointer with PQgetvalue function.

Now, I have a table with 10-20 columns, and I want to print them out with a simple printf call:

printf("%s,%s,%s..(so on...)...%s", resA, resB, resC,..., resN);

where resA to resB are strings loaded using PGgetvalue function. Now, this approach requires 10-20 pointers declared (if I want to print it out with a single printf), and I was going to use something simple as:

char* getFieldVal(PGresult* res, int row, char* fieldName)
{
    static char tmp[1000];
    memset(tmp, 0, sizeof(tmp));

    // Load data here...

    return tmp;
}

and then to call printf like:

printf("%s,%s,%s..(so on...)...%s", 
       getField(r, 0, "A"), getField(r, 0, "B"), ... , getField(r, 0, "N"));

However, output of the printf function is indicating that all getField calls are returning whatever first was requested from the database (in this case, value of the A field), even though I've deleted the previous string (just to be sure) with memset call.

Where am I wrong? Is something in my code, or is gcc assuming that all my getField calls returns pointer to the same memory, so it is not actually calling it mulitple times.

Or, is printf function first evaluating all parameters (in reverse order), and then actually calling the function? If this is the case (and I bet it is), is there any simpler pattern to achieve what I am trying?

Was it helpful?

Solution

Or, is printf function first evaluating all parameters (in reverse order), and then actually calling the function?

Yes.

But there's no need to copy the results since they persist in memory until PQclear(PGresult*) is called.

Starting from your function, you may get the pointer to the value of fieldName for row with:

char* getFieldVal(PGresult* res, int row, char* fieldName)
{
  int n = PQfnumber(res, fieldName);
  if (n == -1)
    return NULL; /* missing field, you might prefer to return an empty string here */
  else
    return PQgetvalue(res, row, n);
}

OTHER TIPS

You're simply returning the address of a static/global variable in this function, so each time you call it, the data is overwritten and the same pointer is returned.

One simpler way of doing this is by looping over the data set and printing each variable separately instead of in a formatted string.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top