如何像 printf 在 while 循环中打印字符一样打印字符?
How do you print characters the same way printf prints characters in a while loop?
我正在尝试复制 printf
,但是我不知道如何让我的行为与 printf
在 while
循环中的行为相同。
这是我正在使用的 while
循环:
while (i-- > 0) {
ft_printf("myprintf");
ft_putchar('\n');
printf("realprintf");
ft_putchar('\n');
}
这是结果
myprintf
myprintf
myprintf
myprintf
myprintf
myprintf
myprintf
myprintf
myprintf
myprintf
realprintfrealprintfrealprintfrealprintfrealprintfrealprintfrealprintfrealprintfrealprintfrealprintf%
这是我目前的 printf
,我比较新,所以代码可能真的很糟糕且效率低下,非常感谢对它的评论
int ft_printf(const char *orgstr, ...)
{
va_list args;
char flagprefix;
int i;
flagprefix = '%';
i = 0;
while(orgstr[i])
{
va_start(args, orgstr);
if(orgstr[i] == flagprefix)
flag_handler(orgstr[i++], args);
else
ft_putchar(orgstr[i]);
i++;
va_end(args);
}
return (0);
}
flag_handler
函数尚未完成,但我给出的示例无论如何都不会调用该函数。
我认为这是经典的缓冲标准输出。你可以打电话给
fflush(stdout);
在循环结束时确保所有内容都发送到屏幕。
你的 printf 版本是怎么写的?
您观察到的问题来自 ft_putchar()
和真实 printf()
使用的不同缓冲机制。您可以通过在 ft_printf()
的开头和结尾处或在 while
循环中的调用之间刷新 stdout
来解决此问题:
while (i-- > 0) {
fflush(stdout);
ft_printf("myprintf");
ft_putchar('\n');
fflush(stdout);
printf("realprintf");
fflush(stdout);
ft_putchar('\n');
fflush(stdout);
}
请注意,您的 ft_printf()
函数框架有问题:
- 您应该在循环开始前用
va_start
初始化 args
一次,而不是针对格式字符串中的每个字符。
- 如果将
va_list
传递给 flag_handler
函数,它的副作用可能不会反映回调用者。您应该直接在 ft_printf()
函数中从可变参数列表中提取参数。
这是修改后的版本:
int ft_printf(const char *orgstr, ...) {
va_list args;
int i, c;
va_start(args, orgstr);
i = 0;
while ((c = orgstr[i++]) != '[=11=]') {
if (c == '%') {
switch (c = orgstr[i++])) {
case 's':
ft_putstr(va_arg(args, char *));
continue;
/* ... handle other cases ... */
case '[=11=]':
break;
default:
ft_putchar(c);
continue;
}
break;
} else {
ft_putchar(c);
}
}
va_end(args);
return 0;
}
我正在尝试复制 printf
,但是我不知道如何让我的行为与 printf
在 while
循环中的行为相同。
这是我正在使用的 while
循环:
while (i-- > 0) {
ft_printf("myprintf");
ft_putchar('\n');
printf("realprintf");
ft_putchar('\n');
}
这是结果
myprintf
myprintf
myprintf
myprintf
myprintf
myprintf
myprintf
myprintf
myprintf
myprintf
realprintfrealprintfrealprintfrealprintfrealprintfrealprintfrealprintfrealprintfrealprintfrealprintf%
这是我目前的 printf
,我比较新,所以代码可能真的很糟糕且效率低下,非常感谢对它的评论
int ft_printf(const char *orgstr, ...)
{
va_list args;
char flagprefix;
int i;
flagprefix = '%';
i = 0;
while(orgstr[i])
{
va_start(args, orgstr);
if(orgstr[i] == flagprefix)
flag_handler(orgstr[i++], args);
else
ft_putchar(orgstr[i]);
i++;
va_end(args);
}
return (0);
}
flag_handler
函数尚未完成,但我给出的示例无论如何都不会调用该函数。
我认为这是经典的缓冲标准输出。你可以打电话给
fflush(stdout);
在循环结束时确保所有内容都发送到屏幕。
你的 printf 版本是怎么写的?
您观察到的问题来自 ft_putchar()
和真实 printf()
使用的不同缓冲机制。您可以通过在 ft_printf()
的开头和结尾处或在 while
循环中的调用之间刷新 stdout
来解决此问题:
while (i-- > 0) {
fflush(stdout);
ft_printf("myprintf");
ft_putchar('\n');
fflush(stdout);
printf("realprintf");
fflush(stdout);
ft_putchar('\n');
fflush(stdout);
}
请注意,您的 ft_printf()
函数框架有问题:
- 您应该在循环开始前用
va_start
初始化args
一次,而不是针对格式字符串中的每个字符。 - 如果将
va_list
传递给flag_handler
函数,它的副作用可能不会反映回调用者。您应该直接在ft_printf()
函数中从可变参数列表中提取参数。
这是修改后的版本:
int ft_printf(const char *orgstr, ...) {
va_list args;
int i, c;
va_start(args, orgstr);
i = 0;
while ((c = orgstr[i++]) != '[=11=]') {
if (c == '%') {
switch (c = orgstr[i++])) {
case 's':
ft_putstr(va_arg(args, char *));
continue;
/* ... handle other cases ... */
case '[=11=]':
break;
default:
ft_putchar(c);
continue;
}
break;
} else {
ft_putchar(c);
}
}
va_end(args);
return 0;
}