variable arguments, odd results

E

Eli Criffield

I'm getting odd results from my fuction that takes variable aguments.

What i want to do is take a printf like format and pass that to
mysql_query then i do some processing of the results and return a
pointer to an array of the results.

Everything works if i guess at the length of the query and malloc that
amount. The problem comes when i try to figure out the size of the
varible arguments.

The way i figure this out below is taking directly from FAQ question
15.4 and 15.5.

I also need to be able to tell the size lquery needs to be even if i
pass it an int or float or whatever, not just strings, is that possible
?

What am i doing wrong?

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

char ***simplesql_query(int *conn, unsigned int *NumberOfRows, unsigned
int *NumberOfFields, char *query, ...)
{
/* parse the query using printf like format and put that all in
lquery */
va_list argp;
char *lquery;
size_t len;
char *p;

/* figure out the size of the query */
va_start(argp, query);
len = strlen(query);
printf("query=%s:len=%d\n",query,len);
while((p = va_arg(argp, char *)) != NULL)
{
/* p has some odd stuff in it, why???? */
printf("len is %d,p is %s\n",len,p);
len += strlen(p);
}
va_end(argp);

/* add one for \0 */
len++;
if ((lquery = malloc(len)) == NULL)
return NULL;

/* pass off query to vsprintf */
va_start(argp, query);
vsprintf(lquery, query, argp);
va_end(argp);

printf("simplesql_query: %s, lentgh=%d\n", lquery,len);

/*
do mysql work stuff

if (mysql_query(conn, lquery) != 0)
simplesql_error(conn,"SELECT failed");
else
...
*/
return NULL;
}


int main()
{
int *conn = 0;
char ***sqlresults;
int rows, fields;


/* odd results */
char userid2[] = "5";
sqlresults = simplesql_query(conn,&rows,&fields,"SELECT UserID FROM
Users WHERE UserID < %s",userid2);

return 0;
}
 
K

kyle york

Greetings,

Eli said:
I'm getting odd results from my fuction that takes variable aguments.

What i want to do is take a printf like format and pass that to
mysql_query then i do some processing of the results and return a
pointer to an array of the results.

Everything works if i guess at the length of the query and malloc that
amount. The problem comes when i try to figure out the size of the
varible arguments.

The way i figure this out below is taking directly from FAQ question
15.4 and 15.5.

I also need to be able to tell the size lquery needs to be even if i
pass it an int or float or whatever, not just strings, is that possible
?

What am i doing wrong?

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

char ***simplesql_query(int *conn, unsigned int *NumberOfRows, unsigned
int *NumberOfFields, char *query, ...)
{
/* parse the query using printf like format and put that all in
lquery */
va_list argp;
char *lquery;
size_t len;
char *p;

/* figure out the size of the query */
va_start(argp, query);
len = strlen(query);
printf("query=%s:len=%d\n",query,len);
while((p = va_arg(argp, char *)) != NULL)

You don't pass a NULL when this function is called, so after the first
pass you're getting whatever garbage is lying around.
{
/* p has some odd stuff in it, why???? */
printf("len is %d,p is %s\n",len,p);
len += strlen(p);
}
va_end(argp);

A better way would be use the return from vsnprintf(0, 0, fmt, argp)
/* add one for \0 */
len++;
if ((lquery = malloc(len)) == NULL)
return NULL;

/* pass off query to vsprintf */
va_start(argp, query);
vsprintf(lquery, query, argp);
va_end(argp);

printf("simplesql_query: %s, lentgh=%d\n", lquery,len);

/*
do mysql work stuff

if (mysql_query(conn, lquery) != 0)
simplesql_error(conn,"SELECT failed");
else
...
*/
return NULL;
}


int main()
{
int *conn = 0;
char ***sqlresults;
int rows, fields;


/* odd results */
char userid2[] = "5";
sqlresults = simplesql_query(conn,&rows,&fields,"SELECT UserID FROM
Users WHERE UserID < %s",userid2);

return 0;
}
 
Z

Zoran Cutura

Eli Criffield said:
I'm getting odd results from my fuction that takes variable aguments.

What i want to do is take a printf like format and pass that to
mysql_query then i do some processing of the results and return a
pointer to an array of the results.

Everything works if i guess at the length of the query and malloc that
amount. The problem comes when i try to figure out the size of the
varible arguments.

The way i figure this out below is taking directly from FAQ question
15.4 and 15.5.

In the suggestion made in FAQ's 15.4. All usage of the function needs a
trailing "(char *) NULL" argument. Your call to the "simplesql_query"
doesn't do so.

If you don't want all you functions to get this NULL pointer in the end,
you should introduce some other way of telling the function how many
arguments there actually are passed.

printf-like functions do this by using %-formats in the format string,
such that va_arg() is only used when there is a %-format in the string.
I also need to be able to tell the size lquery needs to be even if i
pass it an int or float or whatever, not just strings, is that possible
?

What am i doing wrong?

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

char ***simplesql_query(int *conn, unsigned int *NumberOfRows, unsigned
int *NumberOfFields, char *query, ...)
{
/* parse the query using printf like format and put that all in
lquery */
va_list argp;
char *lquery;
size_t len;
char *p;

/* figure out the size of the query */
va_start(argp, query);
len = strlen(query);
printf("query=%s:len=%d\n",query,len);
while((p = va_arg(argp, char *)) != NULL)
{
/* p has some odd stuff in it, why???? */
printf("len is %d,p is %s\n",len,p);
len += strlen(p);
}
va_end(argp);

/* add one for \0 */
len++;
if ((lquery = malloc(len)) == NULL)
return NULL;

/* pass off query to vsprintf */
va_start(argp, query);
vsprintf(lquery, query, argp);
va_end(argp);

printf("simplesql_query: %s, lentgh=%d\n", lquery,len);

/*
do mysql work stuff

if (mysql_query(conn, lquery) != 0)
simplesql_error(conn,"SELECT failed");
else
...
*/
return NULL;
}


int main()
{
int *conn = 0;
char ***sqlresults;
int rows, fields;


/* odd results */
char userid2[] = "5";
sqlresults = simplesql_query(conn,&rows,&fields,"SELECT UserID FROM
Users WHERE UserID < %s",userid2);

return 0;
}
 
E

Eli Criffield

Oh i thought somehow the NULL was va_args way of telling you it
doesn't have any more arguments, i guess if i would have looked closer
at the FAQ i would have seen that it gets passed to there example
function.

using vsnprintf(0,0,query,argp) to figure the size works a lot better
anyway.

I'm kicking myself for not thinking of that.

Thanks

Eli
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,225
Members
46,815
Latest member
treekmostly22

Latest Threads

Top