最近一直在写毕业论文,周末过来记录下一个文件操作的功能。
参考:
https://www.cnblogs.com/xudong-bupt/p/3478297.html
https://www.javatpoint.com/fprintf-fscanf-in-c
一、文件模式
#include <stdio.h>
FILE *fp;
fp=fopen(文件名, 打开方式);
对应于文件流,每一个流都有关联的文件模式,这里以一个表格形式记录模式及对应的意义。
r表示read,w表示write,b表示二进制,t代表text,+代表可读可写
二、fprintf与fscanf的使用
原型:
//used to write set of characters into file. It sends formatted output to a stream.
int fprintf(FILE *stream, const char *format [, argument, ...])
//used to read set of characters from file. It reads a word from the file and returns EOF at the end of file.
int fscanf(FILE *stream, const char *format [, argument, ...])
代码:
#include <stdio.h>
#include <stdlib.h>
void wirteFileArr1D(const char* filename,double arr[],int size)
{
FILE * fp;
if((fp = fopen(filename, "w"))==NULL)
{
printf("cant open the file");
return;
}
//连续写size个double数据
for(int i=0;i<size;++i)
{
fprintf(fp,"%lf\n",arr[i]);
}
fclose (fp);
}
void readFileArr1D(const char* filename,double arr[],int size)
{
FILE * fp;
if((fp=fopen(filename,"r"))==NULL)
{
printf("cant open the file");
return;
}
//连续写size个double数据
for(int i=0;i<size;++i)
{
fscanf(fp,"%lf\n",&arr[i]);
}
for(int i=0;i<size;i++)
printf("%lf\n",arr[i]);
}
int main ()
{
double arr[4] = {1.2,3.14,-0.23,1992};
wirteFileArr1D("data.txt",arr,4);
readFileArr1D("data.txt",arr,4);
return 0;
}
测试:
三、fwrite与fread的使用
原型:
size_t fread ( void * ptr, size_t size, size_t count, FILE * stream );
size_t fwrite ( const void * ptr, size_t size, size_t count, FILE * stream );
参数:
ptr: 指向数据指针
size:每个数据类型的大小
count:数据的个数
stream:文件指针
返回值:
读取或写入数据的个数
读写int数组文件操作
代码:
#include <stdio.h>
#include <stdlib.h>
void wirteFile()
{
FILE * pFile;
int buffer[] = {1, 2, 3, 4};
if((pFile = fopen ("myfile.txt", "wb"))==NULL)
{
printf("cant open the file");
exit(0);
}
//连续写4个int数据
fwrite (buffer , sizeof(int), 4, pFile);
fclose (pFile);
}
void readFile()
{
FILE * fp;
int buffer[4];
if((fp=fopen("myfile.txt","rb"))==NULL)
{
printf("cant open the file");
exit(0);
}
//可以一次读取4个int数据
if(fread(buffer,sizeof(int),4,fp)!=4)
{
printf("file read error\n");
exit(0);
}
for(int i=0;i<4;i++)
printf("%d\n",buffer[i]);
}
int main ()
{
wirteFile();
readFile();
return 0;
}
测试:
对于二进制文件我们使用hexdump查看文件的内容,由此可以观察到内存中数据存储情况。
读取单字节数组到文件操作
#include <stdio.h>
#include <stdlib.h>
void wirteFile()
{
FILE * fp;
unsigned char buffer[12]={0x7E,0x7E,0X10,0X00,0X00,0X00,0X01,0X02,0X03,0X04,0XA5,0XA5};
if((fp = fopen ("myfile.txt", "wb"))==NULL)
{
printf("cant open the file");
exit(0);
}
//连续写12个u8数据
fwrite (buffer , sizeof(unsigned char), 12, fp);
fclose (fp);
}
void readFile()
{
FILE * fp;
unsigned char buffer[12];
if((fp=fopen("myfile.txt","rb"))==NULL)
{
printf("cant open the file");
exit(0);
}
if(fread(buffer,sizeof(unsigned char),12,fp)!=12) //可以一次读取
{
printf("file read error\n");
exit(0);
}
for(int i=0;i<12;i++)
printf("%02x\n",buffer[i]);
}
int main ()
{
wirteFile();
readFile();
return 0;
}
测试:
四、时间日期作为文件名
获取时间戳并将其作为文件名的一部分可用于使用程序多次下载文件,又防止将上次下载的文件覆盖掉,让文件根据时间戳命名即可。
代码1:
time_t currtime = time(NULL);
struct tm* p = localtime(&currtime);
char filename[100] = {0};
sprintf(filename,"%d%02d%02d%02d%02d%02d.txt",p->tm_year+1900,p->tm_mon+1,p->tm_mday,p->tm_hour,p->tm_min,p->tm_sec);
printf("%s\n",filename);
代码2:
time_t t = time(NULL);
char tmp[64];
strftime(tmp, sizeof(tmp), "%Y-%m-%d %H:%M:%S",localtime(&t) );
puts(tmp);
代码3:
time_t nowtime = time(NULL);
struct tm *p1;
p1 = gmtime(&nowtime);
char filename1[256] = {0};
char timeinfo1[256] = {0};
sprintf(filename1,"%d-%d-%d.txt",1900+p1->tm_year,1+p1->tm_mon,p1->tm_mday);
sprintf(timeinfo1,"%d-%d-%d %d:%02d:%02d.txt\n",1900+p1->tm_year,1+p1->tm_mon,p1->tm_mday,8+p1->tm_hour,p1->tm_min,p1->tm_sec);
printf("%s\n",filename1);
printf("%s\n",timeinfo1);
测试: