目录
FILE* fopen(const char* filename,const char* mode);
int fputc(char c,FILE* stream);
int fputs(const char* string,FILE* stream);
char* fgets(char* string,int n,FILE* stream);
int fprintf(FILE* stream,const char* format [, argument ]...);
int fscanf(FILE* stream,const char* format [, argument ]...);
size_t fread(void* buffer,size_t size,size_t count,FILE*stream);
size_t fwrite(const void* buffer,size_t size,size_t count,FILE* stream);
int ferror(FILE* stream); 判断读写时遇到错误而结束
int feof(FILE* stream); 判断读写时文件结束而结束
文件类型分为:
文本文件:以ASCLL字符的形式存储文件。
二进制文件:10的二进制代码形式存储;
需要注意的是:在读取文件的时候。程序并不是直接从硬盘内拿信息的,中间会有一个过度的缓存区,程序,也是通过缓存区获得数据;
也正是因为有缓存区的存在,c语言在操作程序的时候,需要做刷新缓存区或者文件操作结束的时候关闭文件(自带刷新)
文件操作:
FILE* fopen(const char* filename,const char* mode);
错误返回:NULL
mode参数:(可以互相组合使用)
r | 打开一个用于读取的文件。该文件必须存在。 |
w | 创建一个用于写入的空文件。如果文件名称与已存在的文件相同,则会删除已有文件的内容,文件被视为一个新的空文件。 |
a | 追加到一个文件。写操作向文件末尾追加数据。没有文件就会新建一个 |
b | 读取二进制文件,文件必须存在 |
wb+ | 读和写二进制文件,没有就新建一个 |
ab+ | 打开二进制文件,在文件末尾读和写 |
int fclose( FILE *stream );
错误返回:EOF
字符操作:
int fputc(char c,FILE* stream);
成功返回非负值;失败返回EOF
int fgetc(FILE* stream);
成功返回非负值,失败返回EOF;
#incldue <stdio.h>
#include <stdlib.h>
///FILE *fopen( const char *filename, const char *mode );
///int fclose( FILE *stream );
///int fputc( char c, FILE *stream );
///int fgetc(FILE* stream)
int main()
{
FILE* pFILE;
pFILE = fopen("text\\text01.txt", "w");
if (pFILE != NULL)
{
// c 参数是想要写入的字符
fputc('9', pFILE);
fputc('4\n', stdout);
fclose(pFILE);
pFILE = NULL;
}
/// fgetc
int n = fgetc(stdin);
printf("printf-n:%c\n", n);
fputc(n,stdout);
return 0;
}
字符串操作:
int fputs(const char* string,FILE* stream);
成功返回非负值,失败返回EOF;
char* fgets(char* string,int n,FILE* stream);
成功返回string,失败返回NULL;
#incldue <stdio.h>
#include <stdlib.h>
///int fputs( const char* string, FILE *stream );
///int fgets( char* string,int n, FILE *stream );
int main()
{
FILE* pFile;
//打开文件
pFile = fopen("text\\text02.txt", "w");
if (pFile != NULL)
{
//fputs 输出(写入)字符串到文件中
fputs("for example",pFile);
//关闭文件
fclose(pFile);
pFile = NULL;
}
return 0;
}
int main()
{
FILE* pFile;
pFile = fopen("text\\text02.txt", "r");
if (pFile != NULL)
{
char arr[256] = { "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"};
fgets(arr, 255, pFile); //实际读取大小是n-1 还有一位给到\0
printf("%s", arr);
全部读取
//while(fgets(arr, 255, pFile)!=NULL)
// printf("%s", arr);
//关闭文件
fclose(pFile);
pFile = NULL;
}
return 0;
}
写入、读取结构体(格式化)数据
int fprintf(FILE* stream,const char* format [, argument ]...);
成功,返回写入字节数,失败返回负值
int fscanf(FILE* stream,const char* format [, argument ]...);
成功,返回成功转换和匹配的字段数,返回值不包括读取了但是没有匹配好的字段;返回0,没有分配任何字段
失败,EOF
方法速记,下面的方法参数都有些类似,这里归类一下;附录有其他方法的练习代码;
#incldue <stdio.h>
#include <stdlib.h>
//fprintf(stream,"%s",结构体.成员)
int main()
{
struct S s1 = { "zhangsan",24,98.99 };
//打开文件
FILE* pf = fopen("text\\text03.txt", "w");
if (pf == NULL)
{
perror("struct S s1::pf->fopen");
return;
}
//写入文件
fprintf(pf, "%s %d %lf", s1.name, s1.age, s1.d);
//关闭文件
fclose(pf);
pf = NULL;
return 0;
}
fscanf(stream,"%s",结构体.成员);
int main()
{
struct S s2;
//打开文件
FILE* pf = fopen("text\\text03.txt", "r");
if (pf == NULL)
{
perror("struyct S s2 :: pf->fopen");
return;
}
//读取文件
// s2.name 字符串首地址
//&(s2.age) 只能取地址
fscanf(pf, "%s %d %lf", s2.name, &(s2.age), &(s2.d));
//printf("%s %d %lf", s2.name, s2.age, s2.d);
fprintf(stdout, "%s %d %lf", s2.name, s2.age, s2.d);
//关闭文件
fclose(pf);
pf = NULL;
return 0;
}
二进制写入
size_t fread(void* buffer,size_t size,size_t count,FILE*stream);
return : 读取的字节数
err:less than count
size_t fwrite(const void* buffer,size_t size,size_t count,FILE* stream);
成功:返回写入的字节数。
err、end:less than count
#incldue <stdio.h>
#include <stdlib.h>
int main()
{
struct S s3 = { "lisi",25,99.99};
//打开文件
FILE* pf = fopen("text\\text04.txt", "wb");
if (pf == NULL)
{
perror("struct S s3::pf-fopen");
return;
}
//写入文件
fwrite(&s3, sizeof(struct S), 1, pf);
//关闭文件
fclose(pf);
pf = NULL;
return 0;
}
int main()
{
struct S s4 = { 0 };
FILE* pf = fopen("text\\text04.txt", "rb");
if (pf == NULL)
{
perror("struct S s4::pf-fopen");
return;
}
fread(&s4, sizeof(struct S), 1, pf);
fprintf(stdout, "%s %d %lf", s4.name, s4.age, s4.d);
fclose(pf);
pf = NULL;
return 0;
}
读、写文件的状态判断
int ferror(FILE* stream); 判断读写时遇到错误而结束
Tests for an error on a stream. 有错误返回:0;没错误返回非0;
int feof(FILE* stream); 判断读写时文件结束而结束
Tests for end-of-file on a stream. 是末尾返回非0;不是返回0;
文件结束的判定
1. 文本文件读取是否结束,判断返回值是否为EOF (fgetc),或者NULL(fgets)
例如:fgetc判断是否为EOF. fgets判断返回值是否为NULL.
2. 二进制文件的读取结束判断,判断返回值是否小于实际要读的个数。
例如:fread判断返回值是否小于实际要读的个数。
普通文件的判定:
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
int main()
{
int c; //处理EOF
FILE* fp = fopen("text\\text07.txt", "r");
if(!fp)
{
perror("FILE opening failed!");
return;
}
fputs("for example!", fp);
//判断fgetc返回的值,是文件结尾还是EOF
while ((c = fgetc(fp)) != EOF) //return nonzero
{
putchar(c);
}
//判断什么原因结束的
if (feof(fp))
puts("end of file reached successfully");
else if (ferror(fp))
puts("I/O error when reading!");
fclose(fp);
fp = NULL;
return 0;
}
二进制文件的判定:
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
int main()
{
double arr[5] = { 1.0,2.0,3.0,4.0,5.0 };
double b[5] = { 0.0 };
size_t ret_code = 0;
FILE* fp = fopen("text\\text08.txt", "wb");
fwrite(arr, sizeof(arr[0]), 5, fp);
rewind(fp);
fp = fopen("text\\text08.txt", "rb");
//读取数据
int i = 0;
while (ret_code = (fread(b, sizeof(double), 1, fp)))
{
printf("%lf\n", *(b+i));
}
if (feof(fp))
puts("end of file reached successfully");
else if (ferror(fp))
puts("I/O error when reading!");
fclose(fp);
fp = NULL;
return 0;
}
附录:
printf()、fprint():转换文件的、sprintf():转换字符串;
scanf()、fscanf() 、 sscanf();
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
struct S
{
char name[20];
int age;
double d;
};
///int sscanf(const char* buf,cosnt char* format[,arguemnt] )
///int sprintf(const char* buf,cosnt char* format[,arguemnt] )
int main()
{
char arr[256] = { 0 };
struct S s1 = { "mingtian",20,99.5 };
struct S s2 = { 0 };
//结构体(格式化)数据转为字符串
sprintf(arr, "%s %d %lf", s1.name, s1.age, s1.d);
printf("%s\n", arr);
//字符串,转换为结构体
sscanf(arr, "%s %d %lf", s2.name, &(s2.age), &(s2.d));
fprintf(stdout, "%s %d %lf\n", s2.name, s2.age, s2.d);
return 0;
}