I/O 格式化输入和输出函数

    格式化输出是由 5 个printf 函数来处理的。
#include <stdio.h>
int printf(const char *restrict format, ...);
int fprintf(FILE *restrict fp, const char *restrict format, ...);
int dprintf(int fd, const char *restrict format, ...);
               /* 返回值:若成功,都返回输出字符数;若输出出错,都返回负值 */
int sprintf(char *restrict buf, const char *restrict format, ...);
               /* 返回值:若成功,返回存入数组的字符数;若编码出错,返回负值 */
int snprintf(char *restrict buf, size_t n, const char *restrict format, ...);
        /* 返回值:若缓冲区足够大,返回将要存入数组的字符数;若编码出错,返回负值 */

    printf 将格式化数据写到标准输出,fprintf 写至指定的流,dprintf 写至指定的文件描述符,sprintf 将格式化的字符送入数组 buf 中,并在数组尾端自动加一个 null 字节,但该字符不包括在返回值中。由于 sprintf 可能造成由 buf 指向的缓冲区的溢出,所以引入了 snprintf 函数。在该函数中,缓冲区长度是一个显示参数 n,超过缓冲区尾端写的所有字符都会被丢弃。其返回值也不包括结尾的 null 字节。
    注意,虽然 dprintf 不处理文件指针,但这里仍然把它包括在处理格式化输出的函数中。使用 dprintf 不需要调用 fdopen 将文件描述符转换成文件指针,而 fprintf 需要。
    下列 5 种 printf 族的变体类似于上面的 5 种,但是可变参数表“...”变成了 arg。
#include <stdarg.h>
#include <stdio.h>
int vprintf(const char *restrict format, va_list arg);
int vfprintf(FILE *restrict fp, const char *restrict format, va_list arg);
int vdprintf(int fd, const char *restrict format, va_list arg);
               /* 返回值:若成功,都返回输出字符数;若输出出错,都返回负值 */
int vsprintf(char *restrict buf, const char *restrict format, va_list arg);
               /* 返回值:若成功,返回存入数组的字符数;若编码出错,返回负值 */
int vsnprintf(char *restrict buf, size_t n, const char *restrict format, va_list arg);
        /* 返回值:若缓冲区足够大,返回将要存入数组的字符数;若编码出错,返回负值 */

    执行格式化输入处理的是 3 个 scanf 函数及其可变长度参数表版本。
#include <stdio.h>
int scanf(const char *restrict format, ...);
int fscanf(FILE *restrict fp, const char *restrict format, ...);
int sscanf(const char *restrict buf, const char *restrict format, ...);
    /* 返回值:赋值的输入项数;若输入出错或在任一转换前已到达文件尾,都返回 EOF */

#include <stdarg.h>
#include <stdio.h>
int vscanf(const char *restrict format, va_list arg);
int vfscanf(FILE *restrict fp, const char *restrict format, va_list arg);
int vsscanf(const char *restrict buf, const char *restrict format, va_list arg);
    /* 返回值:赋值的输入项数;若输入出错或在任一转换前已到达文件尾,都返回 EOF */

    scanf 族函数用于分析输入字符串,并将字符序列转换成指定类型的变量。在格式之后的各参数包含了变量的地址,用转换结果对这些变量赋值。
    标准 I/O 库最终都要调用底层的 I/O 例程,每个标准 I/O 流都有一个与其相关联的文件描述符,可以对一个流调用 fileno 函数来获取其描述符(如果要调用 dup 或 fcntl 等函数,则需要此函数)。
#include <stdio.h>
int fileno(FILE *fp);    /* 返回值:与该流相关联的文件描述符 */

猜你喜欢

转载自aisxyz.iteye.com/blog/2388123