我试图了解我的可变函数有什么问题。 出于某种原因,它打破了所有可变参数,除了第二个和第三个。
根据文档,函数看起来是正确的:
https://en.cppreference.com/w/c/language/variadic
我用的是C标准17,低于23.
这里是CMake设置中的C标准
cmake_minimum_required(VERSION 3.25)
project(3 C)
set(CMAKE_C_STANDARD 17)
add_executable(${PROJECT_NAME} main.c)
最小的工作测试,显示出奇怪。
#include <stdarg.h>
#include <stdio.h>
void test(const char *fmt, ...) {
va_list args;
va_start(args, fmt);
printf(fmt, args);
va_end(args);
}
int main() {
test("%d %d %d %d %d\n", (unsigned char) (1), (unsigned char) (2), (unsigned char) (3), (unsigned char) (4), (unsigned char) (5));
return 0;
}
操作系统是 Windows 10.
IDE 是 JetBrains CLion 2023.1.1.
工具链选择为 Visual Studio。
编译器是 Microsoft (R) C/C++ Optimizing Compiler Version 19.35.32216.1 for x64。
架构是 64 位 x86。
我看到测试代码的输出如下:
1897200872 2 3 1 1077874749
所以,五个参数中只有两个是正确的。其他论点被打破。
我做错了什么?
谢谢。
更新
好的。我已将
printf
更改为 vprintf
,现在它可以正确打印值。但是一个新的奇怪发生了。
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
char *smprintf(const char *fmt, ...) {
va_list args;
va_start(args, fmt);
int len = vsnprintf(NULL, 0, fmt, args);
va_end(args);
len++;
char *buf = malloc(len);
if (buf == NULL) {
return NULL;
}
va_start(args, fmt);
vsnprintf(buf, len, fmt, args);
va_end(args);
return buf;
}
void test(const char *fmt, ...) {
va_list args;
va_start(args, fmt);
//vprintf(fmt, args);
vprintf("Result: %s.\n", smprintf(fmt, args));
va_end (args);
//free(x);
}
int main() {
test("%d %d %d %d %d\n", (unsigned char) (1), (unsigned char) (2), (unsigned char) (3), (unsigned char) (4), (unsigned char) (5));
return 0;
}
在这里,在
smprintf
函数中,我试图根据格式和参数制作格式化的 C 字符串。
现在
smprintf
函数由于某种原因破坏了所有参数。
进程结束,退出代码为 -1073741819 (0xC0000005)
感谢
dbush
.
工作解决方案如下。
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
char *smprintf(const char *fmt, va_list args) {
int len = vsnprintf(NULL, 0, fmt, args);
len++;
char *buf = malloc(len);
if (buf == NULL) {
return NULL;
}
vsnprintf(buf, len, fmt, args);
return buf;
}
void test(const char *fmt, ...) {
va_list args;
va_start(args, fmt);
vprintf(fmt, args); // Debug.
printf("\n"); // Debug.
va_list argsCopy;
va_copy(argsCopy, args);
char *x = smprintf(fmt, argsCopy);
printf("Result: %s.\n", x);
free(x);
va_end (args);
}
int main() {
test("%d %d %d %d %d", (unsigned char) (1), (unsigned char) (2), (unsigned char) (3), (unsigned char) (4), (unsigned char) (5));
return 0;
}
我现在能够从格式和可变参数创建格式化的 C 字符串。