我正在尝试对C标准功能 printf 进行简单的实现。到目前为止,我只是编写了一些测试代码来帮助我更好地理解变量参数列表的用法。但是,我不知道为什么我的输出中包含多余的一行。
这是我的代码:
#include <stdio.h>
#include <stdarg.h>
#include <unistd.h>
void print_test_helper(char *string, va_list args)
{
while (*string)
{
if (*string == '%')
{
string = string + 2; //increment pointer by two spots to "\n"
printf("%s", (va_arg(args, char*)));
}
else
{
write(1, &*string, 1);
string++;
}
}
}
void print_test(char *string, ...)
{
va_list ap;
va_start(ap, string);
print_test_helper(string, ap);
}
int main()
{
print_test("this is a %s\n", "string");
return 0;
}
我看到它的方式,我的print_test_helper应该继续写传递给它的字符串,直到看到'%'字符为止,此后它会跳到换行符两个位置。然后,该函数调用printf方法以简单地打印出保存在列表中的参数,但是输出如下:
this is a
string
如您所见,它包含一个新行。有什么想法吗?
编辑:
将行printf(“%s”,va_arg(args,char *))更改为write(1,va_arg(args,char *),6);产生预期的行为。这与write和printf之间的交互有关吗?
编辑2:
请参阅下面的答案!
答案 0 :(得分:0)
@Achal为我指出了有关printf中缓冲的正确方向。据此stack overflow post所知,除非满足一些条件,否则不能保证将printf打印到控制台。其中有一些是笨拙,程序退出或换行符。
在我的情况下,该函数正在将每个字符写到stdout(不缓冲写操作),当遇到“%s \ n”时,printf在执行其工作,仅缓冲了它。因此,我的假设是,当将“ \ n”写入标准输出时,printf意识到只有在写入放下换行符之后才需要转储其缓冲区,并且这样做。
正如@ M.M所提到的,混合使用write和printf不是一个好主意,我想这篇文章可以证明这一点。不过,我本来并不想以这种方式结束它,因为我很懒,我只是在使用printf进行测试,但是最终我了解了更多有关其工作原理的信息。干杯。