【发布时间】:2019-09-18 16:50:20
【问题描述】:
我正在尝试简单地实现 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:
请看下面的答案!
【问题讨论】:
-
仔细查看您执行操作的顺序。调试器可能会有很大帮助。
-
混合使用
printf和write不是一个好主意(最好在所有情况下都使用标准CI/O,或者在所有情况下使用POSIX I/O,例如使用@ 987654325@ 而不是write)。标准 C I/O 可以做自己的输出缓冲。 -
当遇到
%时,添加2表示string指向换行符。您需要添加3。&*string和string也是等价的。 -
@Peter 我认为指向换行符是有意的。 (但是那段代码还有另一个问题,如果字符串以
%结尾,它将无限期地读取结尾) -
旁注,
write()系统调用不是缓冲 IO,而库函数printf()是缓冲的。