C++ 中的变量参数列表

发布于 2024-11-01 23:23:56 字数 1821 浏览 0 评论 0原文

我有这个方法(通过使用 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);

  ...

}

我在linux下为GCC编写,但代码应该可以在MinGW和CygWin下运行。

I have this method (by using code from vsnprintf man page):

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

I want to make general function queryFormat which will calculate the size needed for formatted string, allocate memory, print format in it and return the string (not real code, pseudo code):

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>;
}

Then I need to call it from all functions that format queries (not real code):

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);

  ...

}

I write for GCC under linux, but the code should be runnable under MinGW and CygWin.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

身边 2024-11-08 23:23:56

我相信这应该可以帮助任何在这里搜索如何在已经作为参数传递的函数中“重用”va_list 问题的解决方案的人:

// Incorrect:
/*void g(int foo, va_list ap) {
    vprintf("%s %s %s\n", ap);
    vprintf("%s %s %s\n", ap);
}*/

void g(int foo, va_list ap) {
    va_list copy;
    va_copy(copy, ap);
    vprintf("%s %s %s\n", copy);
    va_copy(copy, ap);
    vprintf("%s %s %s\n", copy);
}

void f(int foo, ...) {
    va_list ap;
    va_start(ap, foo);
    g(foo, ap);
    va_end(ap);
}

int main() {
    f(42, "aaa", "bbb", "ccc");
    return 0;
}

I believe this should help anyone who googled here in search of solution to the problem of how to "reuse" a va_list in a function that had it already passed as parameter:

// Incorrect:
/*void g(int foo, va_list ap) {
    vprintf("%s %s %s\n", ap);
    vprintf("%s %s %s\n", ap);
}*/

void g(int foo, va_list ap) {
    va_list copy;
    va_copy(copy, ap);
    vprintf("%s %s %s\n", copy);
    va_copy(copy, ap);
    vprintf("%s %s %s\n", copy);
}

void f(int foo, ...) {
    va_list ap;
    va_start(ap, foo);
    g(foo, ap);
    va_end(ap);
}

int main() {
    f(42, "aaa", "bbb", "ccc");
    return 0;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文