如何像 printf 在 while 循环中打印字符一样打印字符?

How do you print characters the same way printf prints characters in a while loop?

我正在尝试复制 printf,但是我不知道如何让我的行为与 printfwhile 循环中的行为相同。

这是我正在使用的 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;
}