- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
背景:我目前正在尝试“扩展”标准 C 格式,以支持处理特定结构,类似于 Objective-C 扩展 C 格式以允许使用“%@”序列支持 NSString 的方式。
我遇到的一个问题是 vsprintf 在 OS X 和 Linux 上的表现似乎不同(我已经用 Ubuntu 10.10 和 12.04 测试过)。在 OS X 上,它的行为符合我的预期,在调用 vsprintf 之后,调用 va_arg 返回 ms 指针(就好像 vsprintf 函数调用 va_arg 来获取 5)。然而,在 Linux 上,va_list 不会从 vsprintf 改变,并且调用 va_arg 返回 5。
我真的很想找出一种方法来实现此功能,以便它在各个平台上表现一致。假设您可以期望 vsprintf 始终更改 va_list 中的指针以便下次调用 va_arg 时它返回下一个尚未使用的参数,这是错误的吗?
我已经尽可能地简化了我的代码来演示这个问题。在 OS X 上,此代码打印从 malloc 返回的指针的正确地址。在 Linux 上,foo 中的 ms 值变为 5,因此它打印 5。
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
static void foo(void *, ...);
typedef struct {
char *value;
} mystruct;
int main(int argc, char *argv[]) {
mystruct *ms = malloc(sizeof(mystruct));
foo(NULL, "%d %@", 5, ms);
}
void foo(void *dummy, ...) {
va_list args;
va_start(args, dummy);
char buffer[512];
int buffer_ptr = 0;
int i = 0;
char *format = va_arg(args, char *);
buffer[0] = '\0';
for (i = 0; i < strlen(format); i++) {
if (i <= strlen(format) - 1 && (format[i] == '%' && format[i+1] == '@')) {
vsprintf(buffer, buffer, args);
/* can expect the next argument to be a mystruct pointer */
mystruct *ms = va_arg(args, mystruct *);
buffer[buffer_ptr+1] = '\0';
fprintf(stderr, "%p", ms); /* SHOULD NOT PRINT 5 */
/* concatenate here */
} else {
buffer[buffer_ptr++] = format[i];
buffer[buffer_ptr] = '\0';
}
}
va_end(args);
}
最佳答案
您需要使用 va_copy
如果您要多次使用参数列表——不这样做是未定义的行为。您的代码应如下所示:
va_list args;
va_start(args, dummy);
...
char *format = va_arg(args, char *);
...
va_list argsCopy;
va_copy(argsCopy, args);
vsprintf(..., argsCopy);
va_end(argsCopy);
...
mystruct *ms = va_arg(args, mystruct *);
...
va_end(args);
关于c - 与 vsprintf 和 va_list 的平台不一致,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10807310/
__inline int my_sprintf (char *dest,char *format,...) { va_list va; va_start(va,format);
我已经编写了这段代码,但我不确定它是否可以。 size_t sendHeaders(int fd, int seconds, const char* header1, ...) { size_
现在,该程序的目标是通过变量参数列表获取四个名称,并使用 vsprintf() 将它们连接成一个名为“total”的字符串。目前的程序是,只有名字出现在字符串“total”中。请问我该如何解决这个问题
我正在为 HCS12 微 Controller 编写 C 代码,以与 LCD 屏幕连接,作为 Uni 作业的一部分,我遇到一个问题,如果我尝试使用 vsprintf 制作 printf 包装器,则会发
我在使用函数 vsprintf 时遇到问题。 我有 3 个函数来打开、关闭和写入 XML 文件。 open 函数将输入文本的第一个单词存储在数组中,close 函数用该单词关闭标签。问题是,我存储要使
我正在尝试为 cstdio 中的标准 sprintf 函数编写一些包装器。但是,我在运行我的程序时遇到了一些奇怪的行为和访问冲突崩溃。我简化了问题并在下面的代码中重现了它: #include #in
我需要将各种格式字符串打印到一个文件中。我将有与每个字符串关联的整数,与每个字符串中的格式说明符相同数量的整数。大多数字符串不会有相同数量的格式说明符/整数。 因此给定格式字符串 blah blah
因为这 1 行代码,我一直在抓狂。如果我不为 extra 动态分配内存(仅通过 char extra[*cur_size+1];),vsprintf 就会卡住。 char *append(char *
echo vsprintf('%s', 'word'); 根据手册,vsprintf() 函数的第二个参数必须是数组。 但这行得通,正常吗?这有时可能会导致一些错误? 最佳答案 $args 参数自动转
实例 把格式化字符串写入变量中: ? 1
下面的代码返回以下内容: Input was: 6789 Vsprintf Buffer: 54 为什么 vsprintf 缓冲区只返回 54? #include #include void vo
我正在尝试编写一个宏来简化 LOG4CPLUS 的使用。但是我在写宏的时候遇到了一些麻烦。 这是我的 cpp 文件中的内容: Logger logger = Logger::getInstance("
#define printm(X) handleVarArgs X void writeFile(std::string & s) { FILE *fp; fopen("test.tx
我正在为一个类实现一个类似 printf(const char * format, ...) 的方法,我需要确定它输出的确切大小,只给定提供的 format 和 va_list 中给出的参数,然后调用
我正在使用 vsprintf 从一种格式生成一个字符串,并且需要在记录它之前添加一个查找的前置字符串。下面的代码打印了格式字符串,但是我如何在前面加上另一个字符串呢?理想情况下以一种相当有效的方式。
我正在为 syslog 编写一个简单的包装器,使我的程序的日志记录更容易一些,并允许在选择时将日志条目转储到控制台。我定义了以下日志函数 void logDebugFunction (int li
我正在尝试使用 vsprintf() 来输出格式化字符串,但我需要在运行它之前验证我的参数数量是否正确,以防止出现“参数太少”错误。 本质上我认为我需要的是一个正则表达式来计算类型说明符的数量,但是当
vsprintf() 愉快地忽略了以下错误: // I'd like to tell me that there are too many arguments. vsprintf("%d", 1, 2
我试图将我得到的变量参数传递给我调用的另一个函数。我编写了一个示例代码来测试这一点。为什么下面的代码中 my_printf 可以工作,但 my2_printf 不能工作? #include #inc
n 变量的字符串插值通常涉及可变参数函数。在 C 中,是否有类似于 vsprintf 的替代方案,可以采用动态创建的字符串数组而不是 va_list? int foo (char *s, const
我是一名优秀的程序员,十分优秀!