Linux C 文件输入输出函数 fopen()、getc()/fgetc()、putc()/fputc()、fclose()、fprintf()、fscanf()、fgets()、fputs()、fseek()、ftell()、fgetpos()、fsetpos() 详解

时间:2021-09-12 08:40:50
  fopen(打开文件)

定义函数

FILE * fopen(const char * path,const char * mode);

函数说明

参数path字符串包含欲打开的文件路径及文件名,参数mode字符串则代表着流形态。

mode有下列几种形态字符串:

r     打开只读文件,该文件必须存在。
r+   打开可读写的文件,该文件必须存在。
   打开只写文件,若文件存在则文件长度清为0,即该文件内容会消失。若文件不存在则建立该文件。
w+ 打开可读写文件,若文件存在则文件长度清为零,即该文件内容会消失。若文件不存在则建立该文件。
a    以附加的方式打开只写文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾,即文件原先的内容会被保留。
a+  以附加方式打开可读写的文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾后,即文件原先的内容会被保留。

上述的形态字符串都可以再加一个b字符,如rb、w+b或ab+等组合,加入b 字符用来告诉函数库打开的文件为二进制文件,而非纯文字文件。不过在POSIX系统,包含Linux都会忽略该字符。由fopen()所建立的新文件会具有S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH(0666)权限,此文件权限也会参考umask值。

返回值

文件顺利打开后,指向该流的 文件指针 就会被返回。若果文件打开失败则返回 NULL,并把错误代码存在 errno 中。

附加说明

一般而言,开文件后会作一些文件读取或写入的动作,若开文件失败,接下来的读写动作也无法顺利进行,所以在fopen()后请作错误判断及处理。

范例

#include <stdio.h>

int main(int argc, char **argv)
{
FILE *fp;
fp = fopen("/Users/jianbao/ClionProjects/apue/123.c", "a+");
if (fp == NULL)
{
printf("open fail\n");
}
else
{
printf("open success\n");
}
  fclose(fp);

return 0;
}

 

  getc(由文件中读取一个字符)

定义函数

int getc(FILE * stream);

函数说明

getc()用来从参数stream所指的文件中读取一个字符。若读到文件尾而无数据时便返回 EOF。虽然 getc()fgetc() 作用相同,但getc()为宏定义,非真正的函数调用。

注意: getchar()getc(stdin) 作用相同。

返回值

getc()会返回读取到的字符,若返回EOF则表示到了文件尾。

范例

参考 fgetc()。

#include <stdio.h>

int main(int argc, char **argv)
{
FILE *fp;
int c;

fp = fopen("/Users/jianbao/ClionProjects/apue/123.c", "r");
while ((c = fgetc(fp)) != EOF)
{
printf("%c\n", c);
}
fclose(fp);

return 0;
}

 

  putc(将一指定字符写入文件中)

表头文件

#include <stdio.h>

函数说明

putc()会将参数c转为 unsigned char 后写入参数 stream 指定的文件中。虽然 putc()fputc() 作用相同,但 putc()为宏定义,非真正的函数调用。

返回值

putc()会返回写入成功的字符,即参数c。若返回EOF则代表写入失败。

范例

参考fputc()。

#include <stdio.h>

int main(int argc, char **argv)
{
FILE *fp;
char a[28] = "abcdefghijklmnopqrstuvwxyz";
fp = fopen("/Users/jianbao/ClionProjects/apue/123.c", "w");
int i;
for (i = 0; i < 26; i++)
{
fputc(a[i], fp);
}
fclose(fp);

return 0;
}

 

  fprintf(格式化输出数据至文件)

定义函数

int fprintf(FILE * stream, const char * format,.......);

函数说明

fprintf()会根据参数format字符串来转换并格式化数据,然后将结果输出到参数stream指定的文件中,直到出现字符串结束('\0')为止。

返回值

关于参数format字符串的格式请参考printf()。成功则返回实际输出的字符数,失败则返回-1,错误原因存于errno中。

范例

#include <stdio.h>

int main(int argc, char **argv)
{
int i = 150;
int j = -100;
double k = 3.14159;

fprintf(stdout, "%d %f %x \n", j, k, i);
fprintf(stdout, "%2d %*d\n", i, 2, i);

return 0;
}

执行

-100 3.141590 96
150 150

 

  fscanf(格式化字符串输入)

定义函数

int fscanf(FILE * stream, const char *format, ....);

函数说明

fscanf()会自参数stream的文件流中读取字符串,再根据参数format字符串来转换并格式化数据。格式转换形式请参考scanf()。转换后的结构存于对应的参数内。

返回值

成功则返回参数数目,失败则返回-1,错误原因存于errno中。

范例

#include <stdio.h>

int main(int argc, char **argv)
{
int i;
unsigned int j;
char s[5];
fscanf(stdin, "%d %x %5[a-z] %*s %f", &i, &j, s, s);
printf("%d %d %s \n", i, j, s);

return 0;
}

执行

10 0x1b aaaaaaaaa bbbbbbbbbb /*从键盘输入*/
10 27 aaaaa

 

  fseek(移动文件流的读写位置)

定义函数

int fseek(FILE * stream, long offset, int whence);

函数说明

fseek()用来移动文件流的读写位置。参数stream为已打开的文件指针,参数offset为根据参数 whence 来移动读写位置的位移数。

参数

whence为下列其中一种:

  • SEEK_SET:从距文件开头 offset 位移量为新的读写位置。
  • SEEK_CUR:以目前的读写位置往后增加 offset 个位移量。
  • SEEK_END:将读写位置指向文件尾后再增加 offset 个位移量。

当 whence 值为 SEEK_CUR 或 SEEK_END 时,参数 offset 允许负值的出现。

下列是较特别的使用方式:

1) 欲将读写位置移动到文件开头时:fseek(FILE *stream, 0, SEEK_SET); // 等价于 rewind(stream);
2) 欲将读写位置移动到文件尾时:fseek(FILE *stream, 0, SEEK_END);

返回值

当调用成功时则返回0,若有错误则返回-1,errno会存放错误代码。

附加说明

fseek()不像 lseek() 会返回读写位置,因此必须使用 ftell() 来取得目前读写的位置。

范例

#include <stdio.h>

int main(int argc, char **argv)
{
FILE *stream;
long offset;
fpos_t pos;
stream = fopen("/etc/passwd", "r");

fseek(stream, 5, SEEK_SET);
printf("offset=%d\n", ftell(stream));

rewind(stream);
fgetpos(stream, &pos);
printf("offset=%d\n", pos);

pos = 10;
fsetpos(stream, &pos);
printf("offset=%d\n", ftell(stream));

fclose(stream);

return 0;
}

执行

offset=5
offset=0
offset=10