Variadic 函数表现异常

问题描述 投票:0回答:1

我试图了解我的可变函数有什么问题。 出于某种原因,它打破了所有可变参数,除了第二个和第三个。

根据文档,函数看起来是正确的:
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)
c function arguments variadic broken-functionality
1个回答
0
投票

感谢

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 字符串。

© www.soinside.com 2019 - 2024. All rights reserved.