Formatted Printing

来自osdev
跳到导航 跳到搜索

本文将介绍格式化打印的概念(即 printf())。

printf()是如何工作的?

你迈向获得可靠的 printf() 功能的第一步是对其工作的理解。 你有没有试过模仿“va_list”(参数列表)并且带void**,比如说一种特定的语言,(译者注:这里原作者似乎使用特殊排版格式,打乱了原句单词的位置,无法正确翻译)比如... ‎总原则和目标 - ‎本地化 - ‎翻译工具 - ‎某语言官方手册 - 或者类似技术? 这肯定行不通! 你必须使用独立版本的<stdarg.h>(或等效实现)中提供的va_list,以便能够使用可变函数。 假设使用<stdarg.h>,这是printf()的原型

int printf(const char *format, ...);

你见过printf()家族的其他成员吗? 他们是

  • printf():将格式化数据写入stdout
  • fprintf(): 将格式化数据写入流
  • sprintf():将格式化数据写入缓冲区
  • snprintf():将格式化数据写入缓冲区,限制写入的最大字符数
  • vprintf(): 将格式化数据写入 stdout,使用一个 va_list 而不是 ...
  • vfprintf():将格式化数据写入流,使用一个 va_list 而不是 ...
  • vsprintf():将格式化数据写入缓冲区,使用一个 va_list 而不是 ...
  • vsnprintf(): 将格式化的数据写入缓冲区,限制写入的最大字符,使用一个 va_list 而不是 ...

以及抽象层包装...

  • printf(): Wraps over vprintf()
  • fprintf(): Wraps over vfprintf()
  • sprintf(): Wraps over vsprintf()
  • snprintf(): Wraps over vsnprintf()
  • vprintf(): Wraps over vfprintf()
  • vfprintf(): Does the work!
  • vsprintf(): Wraps over vsnprintf() (with a magical number as limit).
  • vsnprintf(): Wraps over vfprintf() with fmemopen()

但是,嘿! 这是一个用户空间C库示例! 是的,是这样的。 你很可能只提供一个 “printf()”,它可以完成 “vfprintf()” 的意图,但可以一次完成。 基本上,worker函数将在它必须打印的地方打印,直到找到一个“%”字符。 如果后跟另一个%,则会打印并处理后续内容。 如果后面跟着一个有效的说明符字符,则开始解析。 否则,字符将被打印出来并继续处理。 我们稍后将详细解释每一项的实现。(译者注:然而并没有……)

常量定义

让我们定义一些常量,稍后我们将大量使用这些常量

#define FLAG_LEFT  0x01 // The '-' flag
#define FLAG_SIGN  0x02 // The '+' flag
#define FLAG_SPACE 0x04 // The ' ' flag
#define FLAG_TYPE  0x08 // The '#' flag
#define FLAG_ZERO  0x10 // The '0' flag

通用占位符(General Recolection)

一旦你在一个 % 之后找到了一些东西,你应该开始声明三个有符号变量:

示例实现

User:A22347/Printf

这个页面正在建设中! 此页面或部分内容仍在改进中,因此可能还不完整。 其内容可能会在不久的将来更改。