文件
在程序设计中,通常有两种文件,它们包括:程序文件和数据文件
程序文件
包括源程序文件(后缀为.c),目标文件(windows环境后缀为.obj),可执行程序(windows环境后缀为.exe)。
数据文件
文件的内容不一定是程序,而是程序运行时读写的数据,比如程序运行需要从中读取数据的文件,或者输出内容的文件。
文件的打开和关闭
要打开和关闭文件,就要涉及到两个函数:fopen() 和 fclose() ,我们先来看一下它的声明。
FILE * fopen ( const char * filename, const char * mode );
返回类型 文件名 打开的方式
int fclose ( FILE * stream );
文件指针
所以我们在打开文件的时候就首先要创建一个文件指针FILE* pf = fopen()
来接收这个函数的返回值。而关于mode的使用方式如下:
使用举例
假设我们当前项目路径中有个文件为data.txt
FILE* pf=fopen("data.txt","w"); // 1 ,以 w 的形式打开这个文件
if(pf==NULL) //如果打开文件失败,那就告诉我们打开失败的原因
{
prinf("%s",strerror(errno));
return 0;
}
fclose(pf); //关闭文件时传入想要关闭的文件的文件指针即可
pf=NULL;
相关细节
1.举例代码中的1位置:如果我们不写出这个文件的完整路径(比如:C:/……/data.txt),那么就是默认在该项目所在路径中打开这个文件。
2.fopen(),中的mode参数记得是双引号,而不是单引号
读写函数
fgetc
函数体:
int fputc ( int character, FILE * stream );
作用:
向文件中写入数据
我们依旧举个例子:
int main()
{
FILE* pf = NULL;
pf = fopen("data.txt", "w");
// ↑ 以“w”的形式打开,如果当前路径不存在这样的文件,那么就会自动创建
if (pf == NULL)
{
printf("%s", strerror(errno));
return 0;
}
fputc('6', pf); -2- 存入一个字符6
fclose(pf);
pf = NULL;
return 0;
}
打完这段代码然后按F5,我们就可以在当前路径中看到这个文件啦,正如我们上面代码所为,成功地存入了一个字符6
fgetc
函数体:
int fgetc ( FILE * stream );
作用:
从文件中读取一个字符(会被提升为整形)
举例:
首先我们先在文件data.txt中存入6789的数据并保存
那么:
int main()
{
FILE* pf = NULL;
pf = fopen("data.txt", "r");
if (pf == NULL)
{
printf("%s", strerror(errno));
return 0;
} //以上为打开文件的相关操作
int ch = 0;
while ((ch = fgetc(pf)) != EOF) //提取文件中的字符(会提升成整形)
{
printf("%c", ch); //打印出来
}
fclose(pf); //关闭文件
pf = NULL;
return 0;
}
输出:
这里需要注意的一个点是:fgetc() 使用过程中,如果文件结束了,那就回返回-1,也就是EOF。
fputs
函数体:
int fputs ( const char * str, FILE * stream );
作用:
向文件中输入字符串
举例:
首先我们把data.txt文件中的内容的清空
int main()
{
FILE* pf = NULL;
pf = fopen("data.txt", "w");
if (pf == NULL)
{
printf("%s", strerror(errno));
return 0;
}
fputs("hello world", pf); //fputs()举例
fclose(pf);
pf = NULL;
return 0;
}
然后F5后,我们打开文件data.txt就可以正常看到我们输入的内容了
fgets
函数体:
char * fgets ( char * str, int num, FILE * stream );
作用:
从文件中读取若干个字符存入str中,如果文件结束,返回NULL
举例:
我们在data.txt中存入hello word后保存
int main()
{
FILE* pf = NULL;
pf = fopen("data.txt", "r");
if (pf == NULL)
{
printf("%s", strerror(errno));
return 0;
}
char res[20] = { 0 };
if(fgets(res, 3, pf)!=NULL) //将读取的数据存入res中
{
printf("%s", res);
}
fclose(pf);
pf = NULL;
return 0;
}
打印出来:
fwrite
函数体:
size_t fwrite ( const void * ptr, size_t size, size_t count, FILE * stream );
指向要写入的元素数组的指针 元素大小 元素个数 流(文件指针)
作用
将数据块写入文件(流)中
注意:函数返回值为真正写入的元素个数
举例:
首先还是把data.txt中的内容清除,然后
int main()
{
FILE* pf = NULL;
pf = fopen("data.txt", "wb"); //注意这里要以二进制写入,“wb”
if (pf == NULL)
{
printf("%s", strerror(errno));
return 0;
} //以上为打开文件的相关操作
char arr[5] = { 'a','[','鸡','汤','?' }; //随便初始化点东西存入
int i = 0;
for (i = 0; i < 5; i++)
{
//每次读取一个元素
fwrite(arr, sizeof(char), 1, pf);
}
fclose(pf); //关闭文件
pf = NULL;
return 0;
}
这样子就完成了数据内容以二进制的形式写入文件了
fread
函数体:
size_t fread ( void * ptr, size_t size, size_t count, FILE * stream );
指向要写入的元素数组的指针 元素大小 元素个数 流(文件指针)
作用
从文件(流)中读取数据
举例:
这边我们结合上文fwrite函数一起食用
int main()
{
FILE* pf = NULL;
pf = fopen("data.txt", "wb"); //注意这里要以二进制写入,“wb”
if (pf == NULL)
{
printf("%s", strerror(errno));
return 0;
} //以上为打开文件的相关操作
char arr[10] = { 'a','[','5','8','?' }; //随便初始化点东西存入
int i = 0;
for (i = 0; i < 5; i++)
{
//每次读取一个元素
fwrite(arr, sizeof(char), 1, pf);
}
fclose(pf); //关闭文件
pf = NULL; //上面是fwrite函数写入的代码
pf = fopen("data.txt", "rb"); //这里要以二进制读取,“rb”
char ch = 0;
while (fread(&ch, 1, 1, pf)) // -1-
{
arr[i] = ch;
i++;
}
printf("%s", arr);
fclose(pf); //关闭文件
pf = NULL;
return 0;
}
然后我们再把这个写入的二进制内容打印出来:
注意: 1位置是将文件中中1个字节的内容赋值给ch
sscanf
函数体:
int sscanf ( const char * s, const char * format, ...);
作用:
可以从字符串中提取出格式化数据
我们举个栗子
假设字符串是个复数的形式,我们现在要把它的实部(54)和虚部(9)提取出来
char arr[]="54+9i";
那么我们先定义两个变量
int real=0,imaginary=0;//分别表示实部和虚部
那么我们现在就可以把这个复数的实部和虚部都提取出来,分别存到real和imaginary中
//arr[]="54+9i"
sscanf(arr,"%d+%di",&real,&imaginary);
注意我们再用的时候一定要注意上面这个形式。
sprintf
函数体
int sprintf ( char * str, const char * format, ... );
作用
把格式化的数据转化成字符串
我们再拿上面那一例子:
给出real=54,imaginary=9,
我们要得出一个字符串ans[]=“54+9i”
char ans[20]={0};
sprintf(ans,"%d+%di",real,imaginary);
这样就可以再次得到ans[]=“54+9i”;