C总结-part_6-文件管理

10_文件

  • 文本文件:基于字符编码,如ASCII、UNICODE
  • 二进制文件

文件打开

FILE *fopen(filename, mode);

// 系统自己定义了一个结构体,叫做FILE
// mode表示打开文件的模式 /* mode的取值 r rb 以只读方式打开 w wb 以写方式打开 a ab 以追加方式打开,在末尾添加内容 r+ rb+ 以可读可写方式打开,不创建新文件 w+ wb+ 以可读可写方式打开,文件如果存在则清空 a+ ab+ 以添加的方式打开文件 Tips:b是指二进制模式,windows专用; */ 
FILE *fp = fopen("xx.txt","r");
if(fp == NULL)
{
    printf("文件打开失败"); return; } printf("打开失败"); fclose(fp); //关闭文件 /* 文件打开失败有几种情况 1、找不到文件,路径不对 2、没有读写权限 3、程序打开文件的数量超出上限(一般是限制65535个文件); */ fputc('A',fp); // 覆盖写入 char ch = fgetc(fp); // 读取一个字符 while(ch == fgetc(fp) != EOF) /* 文件结尾 EOF 默认值是-1; 用一次fgetc,就会从文件中读取一个字符,并且文件中的光标会向前走一步; */ 

char ch;
while((ch = fgetc(fp)) != EOF)
{
    printf("%c\n",ch);
}
// EOF的ASCII值为-1,而ASCII中字符的值全为正,所以可以用来作为结束标志; 


char ch = 'a';
FILE *fp = fopen("./b.txt","a");
fputc(ch,fp);
ch = 'b'; fputc(ch, fp); // 此时b.txt文件内就有了字符串ab 

// 例、实现一个vi编辑器
scanf("%s",fileName);
getchar(); // scanf的结束时用\n,getchar则是用来接收\n,避免多次scanf导致问题;

// 更新缓冲区,比如说录入的时候终端了程序,原有的输入内容用fflush就会被缓存下来; fflush(p); // 目标:使用命令 myvi ./a.txt 就可以对a.txt进行编辑 

// 例、实现cat,即查看文本文件;
// cat ./a.txt  此时就会显示出文件的所有内容
// 例、四则运算
sprint(buf, "%d%c%d=\n",a,b,c);
// 例如键入2*3=\n,就会放入buf中
// 文件的加密解密
/*
简单的加密
    1、读取文件,将里面的字符的ASCII码全部加1,
    2、将读取后处理的内容写入到另外一个文件中;

解密
    1、读取文件,讲礼貌的字符的ASCII码全部减1,
    2、将处理后的内容写入到另一个文件中

Tips:系统md5就是一种常用的加密方式;
*/

按字符读写文件 → 每次使用则读取一个字符

  • 读 fgetc()
  • 写 fputc()
  • 是否到文件结尾 feof()

按行读写文件 → 也叫块读取,可以指定读取的长度

  • 读 fgets()
  • 写 fputs()
char buf[1024];
fgets(buf, 5,fp); 
/*
fp是通过fopen获取到的fileStream
5是读取的数量,在实际读取时,传入5,会读4个字符,还剩1个字符为\0作为字符的结束;
读取的数量可以超过fp的大小
*/

// char 直接定义的buf存放到栈里面,空间有限
char buf[1024]; 

// 使用malloc申请的空间在堆空间内,空间很大
char *uf = malloc(sizeof(char *) * 1024); 
while(feof(fp) == 0){}
/*
feof()判断文件是否到了结尾
    =0  说明没有到结尾
    ≠0  说明已经到了结尾

Tips:EOF是判断字符的结尾,而feof()则是判断文件流是否到末尾
*/
/*
字符串的格式化读出:从buf中,按照"%d%c%d=\n"的格式,提取各个变量值,赋值到abc当中
*/
sscanf(buf, "%d%c%d=\n",&a,&b,&c);


/*
文件的格式化写入:将a b c value按照"%d%c%d=%.2f\n"的格式组成字符串,存入到buf中
*/
fprintf(buf, "%d%c%d=%.2f\n",a,b,c,value); // 上面这句等价于 memset(buf,0,20); sprintf(buf,"%d%c%d=%.2f\n",a,b,c,value); fputs(buf,fp2); /* 文件的格式化读取 */ fscanf(fp1, "%d+%d=%d\n",&a, &b, &c); 

  • scanf() - printf()
  • sscanf() - sprintf()
  • fscanf() - fprintf()
printf("===%5d===",1);
/*
%5d     ____1,前面四个空格
%-5d    1____,后面四个空格
%.5d    00001
%-.5d   00001

%ld     打印long类型
*/
// 例、使用fscanf(),fprintf()实现四则运算写入

// 例、使用结构体完成四则运算读写
// 例、10000个数据排序
/*
Tips:第一个想到的是冒泡排序,但是冒泡的执行次数10000+9999+9998+...
100000个数据排序,冒泡排序用时35s
*/

// 如何记录运行时间?
unsigned int start_time = time(NULL); ...中间执行代码操作... int end_time = time(NULL); end_time - start_time → 即为程序运行时间 /* Tips:对于有规律的数,可以用空间换时间, 例如,100000个1-1000的数,可以定义一个arr[1000],某数i出现的次数作为arr[i]的值 此时可以缩短排序时间到1s */ 

——————————————————————————————————————————————

按块读写

fread(*ptr , size_t , nmemb , stream);

  • ptr 要读写的地址
  • size_t 块的大小
  • nmemb 块数
  • stream 文件流

fwrite( )

总的读写大小 = 块的大小 * 块数

// 移动读写的光标
FILE *fp = fopen("../../d.txt", "r");
fseek(fp, 6 , SEEK_SET);
fseek(fp, -5 , SEEK_END); // 光标向前走n个位置,即使文件光标已经到了开头,仍会有一个相对距离 

ftell(fp); 返回到当前文件的读写位置

rewind(fp) 将光标返回到开头

Tips:windows文本文件以\r\n为结尾,
linux和unix文本文件以\n结尾,
但是,读取时,windows下回自动将\r\n转为\n,如果是以二进制查看则没有这个转换


——————————————————————————————————————————————

删除、重命名文件

remove(pathname)
rename(oldpath, newpath)

成功时返回0
失败时返回-1

——————————————————————————————————————————————

文件缓冲区

int fflush(FILE *stream)
立即将缓冲区的数据写入到文件中

缓存 → 即当前操作的文件内容
更新到文件 → 将当前操作的内容写入到磁盘

程序编译

  • 预处理
  • 编译
  • 汇编
  • 连接

——————————————————————————————————————————————

 

猜你喜欢

转载自www.cnblogs.com/1994july/p/12390594.html
今日推荐