我代码:
#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"
。哪些编译器是正确的,我做错了什么?
2条答案
按热度按时间rbl8hiat1#
字符串
将
va_list
* 通过值 * 传递给函数 * 两次 * 是不正确的。这些只是规则https://port70.net/~nsz/c/c11/n1570.html#7.16p3:对象ap可以作为参数传递给另一个函数;如果该函数调用带有参数ap的va_arg宏,则调用函数中ap的值是不确定的,应在进一步引用ap之前传递给va_end宏
最简单的修复方法是通过指针传递
va_list
。型
一定要考虑使用代码格式化程序。有些IDE甚至有内部的“自动重新格式化”选项。
ryhaxcpt2#
一旦
ft_printf()
将ag
传递给control()
函数,control()
在其副本上调用va_arg()
,ft_printf()
可能不再对原始数据做任何事情,除了将其传递给va_end()
。甚至不能将其传递给control()
的另一个调用。当它这样做时,会产生未定义的行为。您应该能够通过让
control()
接受va_list *
而不是va_list
来解决这个问题,并让ft_printf()
传递适当的地址&ag
。