Chapter5-标准I/O库(下)-「APUE读书笔记」

  • 定位流

1、ftell和fseek

#include

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);                                                //将流设置到文件起始位置

ftello和fseeko类似于ftell和fseek

off_t    ftello(FILE*  fp);

int    fseeko(FILE*  fp,  off_t  offset,  int  whence);      

3fgetpos和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

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

#include

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

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

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);

你可能感兴趣的:(C++/C,读书笔记,Unix/Linux)