C文件读写(二进制/文本文件)整理


打开文件

使用fopen打开文件,在<stdio.h>头文件中,其声明如下:

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

需要指定文件名参数filename以及mode参数来说明用哪种方式打开。

mode参数所支持的字符串有:

参数说明
"r"read: 打开文件作为读取(输入)对象,文件必须已存在。
"w"write: 打开一个空文件作为写入(输出)对象。如果同名文件已存在,那么其原有内容将会被舍弃,然后当成空白文件开始写入内容。
"a"append: 打开一个文件在其末尾写入内容。如果文件不存在则会被创建。读写指针重定位操作(如fseekfsetposrewind)将会被忽略。
"r+"read/update: 打开一个现存文件用于更新(同时支持读取和写入,后通)。
"w+"write/update: 打开一个空白文件用于更新。如果同名文件已存在,那么其中的内容则会被舍弃,当成新的空白文件对待。
"a+"append/update: 打开一个文件用于更新,其中所有输出操作都在文件末尾进行。重定位操作只会影响下一次读取操作,随后读写指针会回到文件末尾。如果文件不存在,则会重新创建。

使用以上mode说明符,文件将以文本形式打开。为了以二进制(binary)形式打开文件,mode说明符中必须包含b字符。使用方法可以是:"rb"、"wb"、"ab"、"r+b"、"w+b"、"a+b",后三种也可以是:"rb+"、"wb+"、"ab+"。

例子:

/* fopen example */
#include <stdio.h>
int main ()
{
  FILE * pFile;
  pFile = fopen ("myfile.txt","w");
  if (pFile!=NULL)
  {
    fputs ("fopen example",pFile);
    fclose (pFile);
  }
  return 0;
}

关闭文件

可以使用fclose关闭文件,在<stdio.h>头文件中,其声明如下:

int fclose ( FILE * stream );

输入的参数是一个FILE对象的指针,用来指定要关闭的stream。若成功关闭,会返回0,否则会返回EOF。见上例。

二进制写入

使用fwrite写入二进制内容,其声明在<stdio.h>文件中:

size_t fwrite ( const void * ptr, size_t size, size_t count, FILE * stream );

共有4个输入参数,分别为:

ptr: 待写入的数组的指针,会被转化为const void *类型。

size: 每个待写入元素的字节大小,size_t为无符号整型变量。

count: 待写入的元素的个数。注:因此最后写入文件的大小为count*size

stream: FILE对象指针,指定一个输出stream。

例子:以二进制形式将二维数组写入文件

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main(void)
{
    FILE *fp = fopen("C_fwrite.bin","wb");
    double m[2][3] = {{1.0,2.0,3.0},{4.0,5.0,6.0}};
    if (fp != NULL) {
        // 写入二维数组
        fwrite(m,sizeof(double),2*3,fp);
    }
    fclose(fp);
    return 0;
}

二进制读取

使用fread读取二进制文件,其声明在<stdio.h>中:

size_t fread ( void * ptr, size_t size, size_t count, FILE * stream );

共有4个参数,意义同fwrite

例子:继续上一个例子,把写入二进制文件中的数组读取并打印出来

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main(void)
{
    FILE *fp = fopen("C_fwrite.bin","rb");
    double m[2][3]={{0.0}};
    if (fp != NULL) {
        fread(m,sizeof(double),6,fp);
    }
    fclose(fp);
    for (int i = 0; i < 2; ++i) 
        for (int j = 0; j < 3; ++j) 
            printf("m[%d][%d]=%f\n",i,j,m[i][j]);
    return 0;
}

编译运行后的结果:

m[0][0]=1.000000
m[0][1]=2.000000
m[0][2]=3.000000
m[1][0]=4.000000
m[1][1]=5.000000
m[1][2]=6.000000

文本文件写入

使用fprintf将C格式化字符串写入文件流中,其声明在<stdio.h>中:

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

共有3个参数:

stream: FILE对象指针,指定一个文件流。

format: 格式化字符串,包含待写入文件流的C字符串。其中可以嵌入格式说明符(format specifiers,以%开头)

...(additional arguments): 附加参数。如果format中含有格式说明符,则需要添加对应的附加参数。格式化字符串中的格式说明符会被替换成指定格式的附加参数的值。

格式说明符遵循以下原型(prototype):

%[flags][width][.precision][length]specifier

其后的说明字符(specifier character)是最重要的,因为它定义了相关参数的类型和解释:

说明符输出实例
di有符号十进制整数-123, 123
u无符号十进制整数123
o无符号八进制0o173
x无符号十六进制整数0x7b
X无符号十六进制整数,大写0X7B
f十进制浮点数,小写10.123
F十进制浮点数,大写,C9910.123
e科学计数法(尾数/指数),小写1.0123e+1
E科学计数法(尾数/小数),大写1.0123E+1
g使用最短表达:%e%f10.123
G使用最短表达:%E%F10.123
a十六进制浮点数,小写,C990x1.43ef9ep+3
A十六进制浮点数,大写,C990X1.43EF9EP+3
c字符a
s字符串
p指针地址b8000000
n不打印任何东西。
相应的参数必须为指向符号整数的一个指针,到目前为止写入的符号数被存入指向的位置
%%后面跟一个%将会输出%本身

格式说明符还能包含子说明符flags占位符,width宽度,.precision精度,modifier(按此顺序),这些都是可选的,下面是各子说明符说明:

flags占位符

占位符说明
-给定的区域宽度中左对齐;默认是右对齐的。
+在结果之前添加符号(+或-)。默认情况下,只有负数前面会添加-号。
(space)如果没有写入符号,那么就会插入一个空格。
#使用oxX说明符,对于不为0的值前面就会带上00x0X。使用aAeEfFgG时,即使没有更多数字,也会添加一个小数点。默认情况下,如果没有小数点后面没有数字,那么就不会写入小数点。
0左边使用0来填充(替换原来的空格填充)

width宽度

宽度说明
(number)指定输出的最小字符数。如果要输出的值比这个数还小,结果会以空格填充。即使结果值比较大,也不会截断。
*宽度未在格式字符串中指定,而是作为必须格式化的参数之前的附加整数值参数。(?)

.precition精度

精度说明
.number对于整数说明符(d, i, o, u, x, X),precision指定要写入的最小位数。如果要写入的值比这个数短,结果就会以0填充。即便要写入的值比这个数长,也不会被截断。
对于a, A, e, E , f, F说明符,这个数指定小数点后的位数,默认值为6。
对于gG说明符,这个数指定尾数的最大位数。
对于s,这个数指定输出的最大字符数,默认情况下所有字符都会被输出,直到末尾遇到null字符串。
.*精度未在格式字符串中指定,而是作为必须格式化的参数之前的附加整数值参数。

例子:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main(void)
{
    FILE *fp = fopen("C_fprintf.txt","w");
    fprintf(fp, "整数:\n");
    fprintf(fp, "-123 d:%d\n", -123);
    fprintf(fp, " 123 d:%d\n", 123);

    fprintf(fp, "-123 i:%i\n", -123);
    fprintf(fp, " 123 i:%i\n", 123);

    fprintf(fp, "-123 u:%u\n", -123);
    fprintf(fp, " 123 u:%u\n", 123);

    fprintf(fp, "-123 o:%o\n", -123);
    fprintf(fp, " 123 o:%o\n", 123);

    fprintf(fp, "-123 x:%x\n", -123);
    fprintf(fp, " 123 x:%x\n", 123);
    fprintf(fp, "-123 X:%X\n", -123);
    fprintf(fp, " 123 X:%X\n", 123);


    fprintf(fp, "浮点数:\n");
    fprintf(fp, "10.123 f:%f\n",10.123);
    fprintf(fp, "10.123 C99 F:%F\n",10.123);

    fprintf(fp, "10.123 e:%e\n",10.123);
    fprintf(fp, "10.123 E:%E\n",10.123);

    fprintf(fp, "10.123 g:%g\n",10.123);
    fprintf(fp, "10.123 G:%G\n",10.123);

    fprintf(fp, "10.123 a:%a\n",10.123);
    fprintf(fp, "10.123 A:%A\n",10.123);


    fprintf(fp, "字符(串):\n");
    fprintf(fp, "a\n");
    fprintf(fp, "hello\n");


    fprintf(fp, "指针地址:\n");
    int a = 1;
    fprintf(fp, "int指针地址 &a=%p\n",&a );


    fprintf(fp, "%%\n");
    fclose(fp);
    return 0;
}

编译运行后结果:

整数:
-123 d:-123
 123 d:123
-123 i:-123
 123 i:123
-123 u:4294967173
 123 u:123
-123 o:37777777605
 123 o:173
-123 x:ffffff85
 123 x:7b
-123 X:FFFFFF85
 123 X:7B
浮点数:
10.123 f:10.123000
10.123 C99 F:
10.123 e:1.012300e+001
10.123 E:1.012300E+001
10.123 g:10.123
10.123 G:10.123
10.123 a:0x1.43ef9ep+3
10.123 A:0X1.43EF9EP+3
字符(串):
a
hello
指针地址:
&a=000000000061FE44
%

文本文件读取

使用fscanf从文件流中按指定格式读取数据,其声明在<stdio.h>文件中:

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

共有3个参数:

stream: FILE对象指针,指定一个文件流。

format: 包含一系列字符的C字符串,这些字符用来控制从文件流中提取数据的格式:

  • 空白符:函数会读取并忽略在非空白字符前的任何空白符(空白符包括空格、换行以及缩进符,即一般所说的\s, \n, \t等)。
  • 非空白符(除%外):函数会继续从文件流中读取下一个非空白或格式说明福之外的字符。
  • 格式说明符:有百分号开头的一个字符序列指定一个格式说明符,它被用来指定从文件流中读取数据的格式和类型。

... (additional arguments): 附加参数。用来指定format中格式字符串所提取到的字符的存储位置,按指定的类型存储。因此,其数量要和格式字符串的数量相同。

fscanf所使用的格式说明符遵循以下原型(prototype):

%[*][width][length]specifier

相关说明类似于fprintf

例子:读取上一个例子中生成的C_fprintf.txt中的前3个元素

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main(void)
{
    char s1[10],s2[10];
    int d;
    FILE *fp = fopen("C_fprintf.txt","r");
    fscanf(fp,"%s %d %s",s1,&d,s2);
    printf("have read:\n%s \n%d \n%s\n",s1,d,s2 );
    return 0;
}

编译运行后的结果:

have read:
整数:
-123
d:-123

参考:http://www.cplusplus.com/

转载于:https://www.cnblogs.com/xfy-learning/p/11519200.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值