- 定位流
1、ftell和fseek
#include<stdio.h>
long ftell(FILE* fp); //成功返回当前位置,出错返回-1
//成功返回0,出错返回-1。
//whence(SEEK_SET起始位置开始,SEEK_CUR当前位置开始,SEEK_END结尾开始)
int fseek(FILE* fp, long offset, int whence);
void rewind(FILE* fp); //将流设置到文件起始位置
2、ftello和fseeko类似于ftell和fseek
off_t ftello(FILE* fp);
int fseeko(FILE* fp, off_t offset, int whence);
3、fgetpos和fsetpos
int fgetpos(FILE* restrict fp, fpos_t* restrict pos); //将文件位置放入pos中
int fsetpos(FILE* restrict fp, const fpos_t* pos); //成功返回0,失败返回非0
- 格式化I/O
1、格式化输出
#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* format, ...); //成功返回将要存入数组的字符数,失败返回负
//代码片段 char temp[16] = "ABCDEFG12345678"; cout << printf("%s ", temp) << endl; cout << fprintf(stdout, "%s ", temp) << endl; cout << dprintf(STDOUT_FILENO, "%s ", temp) << endl; char buf[16]; cout << sprintf(buf, "%s", temp) << endl; cout << buf << endl; char buf2[8]; cout << snprintf(buf2, 8, "%s", temp) << endl; cout << buf2 << endl; //输出: ABCDEFG12345678 16 ABCDEFG12345678 16 ABCDEFG12345678 16 15 ABCDEFG12345678 15 ABCDEFG
可以看到sprintf会造成缓冲区的溢出,而snprintf就要安全得多。
format参数组成:
%[flag][fldwitdth][precision][lenmodifier]convtype
flag: 撇号, 将整数按千位分组(试了一下并不能)
减号- 左对齐
加号+ 显示带符号转换的正负号
空格 如果第一个不是正负号,则补充空格
井号# 指定另一种转换形式
零 0 填充0
fldwidth:最小字段宽度,多余字符用空格或0填充,非负十进制数或一个星号(*)
precision:整型最少位数,浮点数小数点后位数,字符串最大字节数,点(.)后加非负整数或星号
lenmodifier:参数长度
hh signed或unsigned char输出
h signed或unsigned short输出
l signed或unsigned long输出
ll signed或unsigned long long 输出
j intmax_t或unitmax_t
z size_t
t ptrdiff_t
L long double
contype:必须要有。
d,i 有符号十进制
o 无符号八进制
u 无符号十进制
x,X 无符号十六进制
f,F 双精度浮点
e,E 指数格式双精度浮点
g,G 根据转换后的值解释为f,F,e,E
a,A 十六进制指数格式双数度浮点
c 字符
s 字符串
p 指向void 的指针
n 输出字符串的长度存入一个指针中 printf("hello%n", length); *length 为5
% %字符
C 宽字符(等同lc)
S 宽字符串(等同ls)
printf族的5个变体,将可变参数表的确成了va_list型的arg
#include<stdio.h>
#include<stdarg.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* format,va_list arg); //成功返回存入数组的字符数,失败返回负
2、格式化输入
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。
scanf族函数的format与printf族相同,同时也有类似的vscanf族函数
#include<stdarg.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);