У меня есть этот метод (с использованием кода из справочной страницы vsnprintf):
MYSQL_RES *nsDatabase::queryf(const char *fmt,...){
int n, size = 1024;
char *query=NULL,*np;
va_list ap;
if (this->dbLink == NULL){
return NULL;
}
query = (char *) malloc (size);
if (query == NULL) return NULL;//memory error
while (1) {
va_start(ap, fmt);
n=vsnprintf(query,size,fmt,ap);
va_end(ap);
if (n > -1 && n < size){// format string succeeded
break;
}
if (n > -1) /* glibc 2.1 */
size = n+1; /* precisely what is needed */
else /* glibc 2.0 */
size *= 2; /* twice the old size */
np = (char *) realloc (query, size);
if (np == NULL) {
printf("memory error\n");
FREE(query);
return NULL;//again memory error
} else {
query = np;
}
}
MYSQL_RES *r = this->query(query);
FREE(query);
if(r == NULL){
return NULL; //mysql error
}
return mysql_store_result(this->dbLink);
}
Я хочу сделать общую функцию queryFormat
, которая будет вычислять размер, необходимый для форматированной строки, выделять память, формат печатив нем и вернуть строку (не реальный код, псевдокод ):
char *queryFormat(const char *fmt, va_list ap){
// allocate memory
// problem - can I use vsnprintf multiple times here (to determine the size of formatted string and allocate memory)
return <formatted string>;
}
Затем мне нужно вызвать его из всех функций, которые форматируют запросы (не реальный код):
queryRow(const char *fmt,...){
va_start(ap, fmt);
// I need to call vsnprintf many times in queryFormat ... Do I need to call va_start() before every call to fsnprintf ?
char * formattedQuery = queryFormat(query, size, fmt, ap);
va_end(ap);
MYSQL_RES *r = this->query(formattedQuery);
free(formattedQuery);
...
}
Я пишу для GCC под Linux, но код должен работать под MinGW и CygWin.