2013-04-02 48 views
0

我正在使用PostgreSql C库libpq,并且我可以从PGresult指针中使用PQgetvalue函数获取值。使用静态字符数组创建帮助函数

现在,我有10-20列的表,我想打印出来用一个简单的printf电话:

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

其中resAresB的字符串中使用PGgetvalue功能加载。现在,这种方法需要声明10-20指针(如果我想用一个单一的printf打印出来),我打算用一些简单的:

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

    // Load data here... 

    return tmp; 
} 

,然后调用printf,如:

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

然而,printf函数的输出表明所有getField调用返回的任何第一次被从数据库中请求(在这种情况下,A领域的价值),即使我已经删除了以前的字符串(只可以肯定)用memset打电话。

我在哪里错了?是我的代码中的东西,或者是gcc,假设我所有的getField调用都返回指向同一内存的指针,所以它实际上并没有调用它多次。

或者,是printf函数首先评估所有参数(按相反顺序),然​​后实际调用函数?如果是这种情况(我敢打赌是这样),有没有更简单的模式来实现我所尝试的?

+0

如果我没有错的,因为你正在使用静态数组和printf的调用()这难道不是未定义在C中的行为? –

+0

关键是你要返回一个指向同一内存的指针,所以在最后一个表达式评估结束后会有三次打印。 – teppic

+0

是的,我虽然是这样(请参阅我的最后一段)。这实际上是有道理的,因为在调用函数之前,必须评估所有参数。 –

回答

1

或者,是printf函数首先评估所有参数(反向 顺序),然​​后实际调用函数?

是。

但是没有必要复制结果,因为它们在内存中一直存在,直到调用PQclear(PGresult*)

从功能出发,你可以得到的指针的fieldName的价值row有:

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); 
} 
+0

是的,我在阅读libpq文档前半小时就已经结束了!谢谢! –

1

你只是在这个函数中返回一个静态/全局变量的地址,所以每次调用它时,数据都会被覆盖,并返回相同的指针。

这样做的一个简单方法是循环数据集并单独打印每个变量而不是格式化的字符串。