文件操作
文件分类
按文件的逻辑结构:
- 记录文件
- 流式文件
按存储介质:
- 普通文件
- 设备文件
按数据的组织形式:
- 文本文件
- 二进制文件
文件api
文件读写:
fgetc,fputc
,字符读写fgets,fputs
,行读写fread,fwrite
,块读写,格式化读写
文件控制;文件是否结束;文件指针的定位、跳转。
文件名有两种写法:c:\\1.txt
,c:/2.txt
。后者在windows和linux下通用。
文件打开模式:
w+
:打开文件并读写。文件若不存在,则创建文件; 文件存在,则清空.
r+
:打开文件并读写。文件若不存在,则报错文件不存在。
a+
:打开文件并读添。文件若不存在,则创建文件。打开后读取时,在文件开头位置; 写入时,添加到文章末尾,并且指针位于添加后的末尾,所以再次读取会乱码。
/*
字符读写和行读写
*/
#include<stdio.h>
#include<string.h>
int main(int argc, char *argv[])
{
FILE *fp = NULL;
char *filename = "1.txt";
char a[10] = "abcdefg";
char buf[26];
int i;
int len = strlen(a);
fp = fopen(filename,"w+");
if(fp == NULL)
{
perror("fopen() error.");
return -1;
}
printf("fopen()\n\n");
for(i = 0; i < len; i++)
{
fputc(a[i],fp);
}
printf("fputc()...\n");
rewind(fp);
printf("rewind()...\n");
while(!feof(fp))
{
printf("%c",fgetc(fp));
}
printf("\n\n");
// rewind(fp);
// printf("rewind()...");
fputs("\nhigk",fp);
printf("fputs(\"\\nhigk\",fp)...\n");
rewind(fp);
printf("rewind()...\n");
while(!feof(fp))
{
//char* fgets (char* buf, int max_bufsize, FILE* fp);
// return buf;
// end with \n\0
char *p = fgets(buf,26,fp);
if(p == NULL)
{
perror("fgets() error.");
if(fp != NULL)
{
fclose(fp);
fp = NULL;
return 0;
}
}
printf("%s",p);
}
printf("\n\n");
if(fp != NULL)
{
fclose(fp);
fp = NULL;
}
return 0;
}
/*
块读写
*/
#include<stdio.h>
struct Person{
char name[10];
int age;
};
int main(int argc, char *argv[])
{
struct Person persons[3];
struct Person persons_read[3];
FILE *fp = NULL;
char *filename = "person.data";
int i;
int retn;
int length = sizeof(struct Person);
fp = fopen(filename,"wb+");
if(fp == NULL)
{
perror("fopen() error.");
return -1;
}
printf("fopen()\n\n");
for(i = 0; i < 3; i++)
{
sprintf(persons[i].name,"foobar%d",i+1);
persons[i].age = i + 10;
}
for(i = 0; i < 3; i++)
{
//size_t fwrite (const void * ptr, size_t size, size_t count, FILE * stream);
// count : how many times to write.
// return the number of times that writes successfully.
retn = fwrite(&persons[i],length,1,fp);
}
printf("fwrite() 3 times.\n");
rewind(fp);
printf("rewind()...\n");
for(i = 0; i < 3; i++)
{
retn = fread(&persons_read[i],length,1,fp);
}
printf("fread() 3 times.\n");
for(i = 0; i < 3; i++)
{
printf("name:%s, age:%d\n",persons_read[i].name,persons_read[i].age);
}
if(fp != NULL)
{
fclose(fp);
fp = NULL;
}
return 0;
}
配置文件项目示例
/*
main.c
*/
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include "cfg_op.h"
void menu();
int TestWriteCfg();
int TestReadCfg();
int main()
{
int choose;
while (1)
{
menu();
printf("please input your choice:");
scanf_s("%d",&choose);
fflush(stdin);
switch (choose)
{
case 1:
TestWriteCfg();
break;
case 2:
TestReadCfg();
break;
case 0:
exit(0);
default:
break;
}
}
return 0;
}
void menu()
{
printf("=================\n");
printf("1 write config file test.\n");
printf("2 read config file test.\n");
printf("0 exit\n");
printf("=================\n");
}
int TestReadCfg()
{
char name[BUFSIZE] = { 0 };
char value[BUFSIZE] = { 0 };
int ret;
int valuelen;
printf("please input the key:");
scanf_s("%s", name, BUFSIZE);
fflush(stdin);
ret = GetCfgItem(CFGNAME, name, value, &valuelen);
if (ret != 0)
{
return ret;
}
else
{
printf("%s = %s\n", name, value);
}
return ret;
}
int TestWriteCfg()
{
char name[BUFSIZE] = {0};
char value[BUFSIZE] = {0};
int ret;
printf("please input the key:");
scanf_s("%s",name, BUFSIZE);
fflush(stdin);
printf("please input the value:");
scanf_s("%s", value, BUFSIZE);
fflush(stdin);
ret = WriteCfgItem(CFGNAME, name, value, strlen(value));
if (ret != 0)
{
perror("WriteCfgItem() error.");
return ret;
}
getchar();
return ret;
}
/*
cfg_op.h
*/
//#pragma once
#ifndef __CFG_OP_H__
#define __CFG_OP_H__
#ifdef __cplusplus
extern "C" {
#endif
#define BUFSIZE 1024
#define CFGNAME "mycfg.ini"
int GetCfgItem(char *pFilename, char *pKey, char *pValue, int *pValueLen);
int WriteCfgItem(char *pFilename, char *pKey, char *pValue, int itemValueLen);
#ifdef __cplusplus
}
#endif
#endif
/*
cfg_op.c
*/
#include<stdio.h>
#include<string.h>
#include "cfg_op.h"
int GetCfgItem(char *pFilename, char *pKey, char *pValue, int *pValueLen)
{
FILE *fp = NULL;
char lineBuf[BUFSIZE];
char *ptmp = NULL, *pbegin = NULL, *pend = NULL;
int ret;
int flag = 0;
ret = fopen_s(&fp,pFilename,"r");
if (ret != 0)
{
printf("fopen_s() error.");
return ret;
}
while (!feof(fp) && flag == 0)
{
memset(lineBuf, 0, BUFSIZE);
fgets(lineBuf,BUFSIZE,fp);
//confirm firstly
ptmp = strstr(lineBuf, pKey);
if(ptmp == NULL)
{
continue;
}
ptmp = strchr(lineBuf, '=');
if (ptmp == NULL)
{
continue;
}
ptmp = strchr(lineBuf, '=') + 1;
//printf("%s = %s", pKey, ptmp);
//strip the spaces
while (1)
{
if (*ptmp == ' ')
{
ptmp++;
}
else
{
pbegin = ptmp;
if (*pbegin == '\n')
{
printf("%s has no value.\n",pKey);
fclose(fp);
fp = NULL;
return -1;
}
break;
}
}
while (1)
{
if (*ptmp == ' ' || *ptmp == '\n')
{
pend = ptmp;
break;
}
else
{
ptmp++;
}
}
flag = 1;
}
if (fp != NULL)
{
fclose(fp);
fp = NULL;
}
if (flag == 1)
{
// found
*pValueLen = pend - pbegin;
memcpy(pValue,pbegin,*pValueLen);
//strcpy_s(pValue, *pValueLen, pbegin); //error. For there is no '\0'.
pValue[*pValueLen] = '\0';
}
else
{
printf("key [ %s ] not found.\n",pKey);
return -2;
}
return 0;
}
int WriteCfgItem(char *pFilename, char *pKey, char *pValue, int itemValueLen)
{
/*
if file exists(branch 1):
if pKey exists: flag = 1, recreate the file.
else: add pKey = pValue directly.
else(branch 2):
create the file, write key-value, then return.
*/
FILE *fp = NULL;
char lineBuf[BUFSIZE] = {0};
char fileBuf[BUFSIZE * 8] = { 0 };
char *ptmp = NULL;
int ret;
long filelen;
int flag = 0; // 0 : key not exists.
// r+ mode firstly
ret = fopen_s(&fp,pFilename,"r+");
if (ret != 0)
{
ret = fopen_s(&fp, pFilename, "w+");
if (ret != 0)
{
printf("fopen_s(filename,\"wt+\") error: %d\n",ret);
//perror("fopen_s(filename,\"wt+\") error.");
return ret;
}
/*
branch 2
*/
fprintf(fp, "%s = %s\n", pKey, pValue);
fclose(fp);
fp = NULL;
return 0;
}
/*
branch 1
*/
//check whether the file size is greater than BUFSIZE
fseek(fp, 0L, SEEK_END);
filelen = ftell(fp);
if (filelen > BUFSIZE * 8)
{
if (fp != NULL)
{
fclose(fp);
fp = NULL;
return -1;
}
}
fseek(fp,0L,SEEK_SET);
while(!feof(fp))
{
memset(lineBuf, 0, BUFSIZE);
ptmp = fgets(lineBuf,BUFSIZE,fp);
if (ptmp == NULL)
{
//printf("fgets() error.\n");
break;
}
ptmp = strstr(lineBuf,pKey);
if (ptmp == NULL)
{
strcat_s(fileBuf,sizeof(fileBuf),pKey);
continue;
}
else
{
/*
the key exists. we should overlay it.
*/
flag = 1;
sprintf_s(lineBuf,BUFSIZE,"%s = %s\n",pKey,pValue);
strcat_s(fileBuf, sizeof(fileBuf), lineBuf);
break;
}
}
if (flag == 0) //the key doesn't exist. Write directly.
{
fprintf(fp, "%s = %s\n", pKey, pValue);
}
else //the key exists. Recreate the file.
{
ret = fopen_s(&fp, pFilename, "w+");
if (ret != 0)
{
printf("fopen_s(filename,\"w+\") error.\n");
return ret;
}
fputs(fileBuf,fp);
}
if (fp != NULL)
{
fclose(fp);
fp = NULL;
}
return 0;
}
大文件加解密
功能实现;
- 加解密接口测试
- 过程:数据move/copy–>加解密
- 数据加解密有两种:有padding和无padding