Vscode/gcc和在线编译器之间的不同输出

6l7fqoea  于 4个月前  发布在  Vscode
关注(0)|答案(2)|浏览(77)

我代码:

#include <stdio.h>
#include <unistd.h>
#include <stdarg.h>

void
ft_putchar(int a)
{
    write(1, &a, 1);
}

void
control(va_list ag, const char c)
{
    if (c == 'c')
        ft_putchar(va_arg(ag, int));
}

void
ft_printf(const char *format, ...)
{
    va_list ag;

    va_start(ag, format);
    int i = 0;

    while (format[i]) {
        if (format[i] == '%') {
            i++;
            control(ag, format[i]);
            i++;
        }
        else {
            write(1, &format[i], 1);
            i++;
        }
    }
    va_end(ag);
}

int
main()
{
    char a = 'Z';
    char b = 'y';

    ft_printf("mer%chaba%c", a, b);
}

字符串
我想写"merZhabay",但在vscode和gcc中它写"merZhabaZ"。但在python tutor和onlinegdb等在线编译器上写"merZhabay"。哪些编译器是正确的,我做错了什么?

rbl8hiat

rbl8hiat1#

void control(va_list ag

字符串
va_list * 通过值 * 传递给函数 * 两次 * 是不正确的。这些只是规则https://port70.net/~nsz/c/c11/n1570.html#7.16p3:
对象ap可以作为参数传递给另一个函数;如果该函数调用带有参数ap的va_arg宏,则调用函数中ap的值是不确定的,应在进一步引用ap之前传递给va_end宏
最简单的修复方法是通过指针传递va_list

void control(va_list *ag, const char c) {
   if(c == 'c')
       ft_putchar(va_arg(*ag, int));
}
....
  control(&ag, format\[i\]);


一定要考虑使用代码格式化程序。有些IDE甚至有内部的“自动重新格式化”选项。

ryhaxcpt

ryhaxcpt2#

一旦ft_printf()ag传递给control()函数,control()在其副本上调用va_arg()ft_printf()可能不再对原始数据做任何事情,除了将其传递给va_end()。甚至不能将其传递给control()的另一个调用。当它这样做时,会产生未定义的行为。
您应该能够通过让control()接受va_list *而不是va_list来解决这个问题,并让ft_printf()传递适当的地址&ag

相关问题