【问题标题】:Why does the output of my program contain an extra newline?为什么我的程序的输出包含一个额外的换行符?
【发布时间】: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:

请看下面的答案!

【问题讨论】:

  • 仔细查看您执行操作的顺序。调试器可能会有很大帮助。
  • 混合使用printfwrite 不是一个好主意(最好在所有情况下都使用标准CI/O,或者在所有情况下使用POSIX I/O,例如使用@ 987654325@ 而不是 write)。标准 C I/O 可以做自己的输出缓冲。
  • 当遇到% 时,添加2 表示string 指向换行符。您需要添加3&amp;*stringstring 也是等价的。
  • @Peter 我认为指向换行符是有意的。 (但是那段代码还有另一个问题,如果字符串以% 结尾,它将无限期地读取结尾)
  • 旁注,write() 系统调用不是缓冲 IO,而库函数 printf() 是缓冲的。

标签: c printf


【解决方案1】:

@Achal 为我指出了有关在 printf 中缓冲的正确方向。据我所知stack overflow post,除非满足一些条件,否则 printf 不能保证打印到控制台。其中一些是 fflush、程序退出或换行符。

在我的例子中,该函数将每个字符写入标准输出(写入未缓冲),当它遇到“%s\n”时,printf 正在执行它的工作,只是它被缓冲了。所以我的假设是,当“\n”被写入标准输出时,printf 意识到它需要转储它的缓冲区并且它这样做,只有在 write 放下换行符之后。

正如@M.M 所提到的,混合 write 和 printf 并不是一个好主意,我想这篇文章就是证明。我并不打算以那样结束它,因为我很懒,所以我只是使用 printf 进行测试,但我最终了解了更多关于它是如何工作的。干杯。

【讨论】:

    猜你喜欢
    • 2018-12-29
    • 1970-01-01
    • 1970-01-01
    • 2017-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多