一、文件的分类

1、文本文件:打开之后能看得懂的文件

2、二进制文件:打开之后看不懂,类似乱码之类的文件(视频,音频打开之后,能看、听,是应为电脑中装有播放器,播放器中含有解码器)。

二、操作文件的步骤和方式

操作步骤:

1、打开文件

2、操作文件

3、关闭文件

操作方式:

文件流:操作文件就像水流一样,将一个大的文件分成一段一段的流过去。

好处:分段操作,避免出现阻塞,卡死的发生。

三、操作文件的函数

1、fopen函数:
/*
fopen函数:
fopen(路径,操作方式);
fopen("/Users/ios/Desktop/1.txt", "r");
绝对路径:文件的全路径
相对路径:相对于当前文件所在的路径 r: 以只读的方式打开文件,如果文件存在,返回文件的指针,如果不存在返回NULL
w: 以只写的方式打开文件,覆盖原文件再返回文件指针,如果不存在则创建再返回文件指针
a: 以追加的方式打开文件,如果文件存在,则追加原来的文件内容,如果不存在则创建文件。不管存在不存在最终都会返回文件指针 r+:功能和r还是一样,只不过增加了写的功能
w+:功能和w还是一样,只不过增加了读的功能
a+:功能和a还是一样,只不过增加了读的功能 以下不能单独用,要跟上面的嵌套一起
t: 代表操作的是文本文件 (默认的) rt wt at rt+ wt+ at+
b: 代表操作的是二进制文件 rb wb ab rb+ wb+ ab+ 在mac或者Linux或者UNIX下,t和b没有区别。 \n 在windows下有区别
\r\n 区别就在于,如果你在windows下面,写入的是文本文件,那么会把所有的换行或者说所有的\n替换成\r\n,二进制不会替换。 在mac或者Linux或者UNIX下,无论写入文本文件还是二进制文件,\n都不会做任何替换。 文件指针就叫 FILE指针。 注意:四个字都要大写。 用r打开,文件不存在返回NULL(0).
注意:NULL 就是 0 16进制0x0
如果不存在,就不能读取里面的内容,所以我们在读取之前应该判断是否不为NULL .
*/ #include <stdio.h>
#include <string.h>int main(int argc, const char * argv[]) {
FILE *fp; //变量名叫fp 是FILE指针
fp = fopen("/Users/ios/Desktop/1.txt", "r");
//FILE *fp = fopen("/Users/ios/Desktop/1.txt", "r");
fclose(fp);
return ;
}
2、fgetc函数
/*
fgetc函数:
用法:fgetc(文件指针);
作用:读取一个字符。 返回值读取到的字符。 例:char ch = fgetc(fp); 如果文件读取到末尾会读取到一个特殊字符叫 EOF,所以如果读取到EOF了,那么代表结束了。 EOF就是文件结束的标识符,读取到EOF就代表文件读取完了。 fputc:
语法:fputc(要写入的字符,文件指针);
作用:写入一个字符到文件
*/
#include <stdio.h>
#include <string.h> void readFile(){
FILE *fp;
//假设文件内容为 abc
fp = fopen("/Users/ios/Desktop/1.txt", "r");
if (fp != NULL) { //需要判断文件指针不为NULL才能操作
//操作
/*
char ch = fgetc(fp);
printf("%c\n",ch); //a char ch2 = fgetc(fp);
printf("%c\n",ch2); //b char ch3 = fgetc(fp);
printf("%c\n",ch3); //c
*/ while () { //因为不知道文件有多少字符,所以死循环
char ch = fgetc(fp); //读取字符·
if (ch == EOF) { //判断读取的字符是不是文件末尾
break; //如果是则退出循环
}
printf("%c",ch); //否则打印出读取到的内容
}
fclose(fp); //一定要加fclose
}
} int main(int argc, const char * argv[]) { return ;
}

3、fputc函数

/*
fputc:
语法:fputc(要写入的字符,文件指针); 作用:写入一个字符到文件。
*/
void writeFile(){
FILE *fp = fopen("/Users/ios001/Desktop/1.txt", "w"); //写
if(fp != NULL ){
char str[] = "hello";//数组长度为6
int len = strlen(str); //计算字符串实际长度 只能算得5
for (int i = ; i<len; i++) {
//循环打印每个字符
fputc(str[i], fp); //str[0],str[1],str[2],str[3],str[4]
}
//操作文件
/*
fputc('h', fp);
fputc('e', fp);
fputc('l', fp);
fputc('l', fp);
fputc('o', fp);
*/ //操作完成的提示
printf("结束!"); //关闭
fclose(fp);//只有在关闭之后,文件中才会有写入的文本。
}
} int main(int argc, const char * argv[]) {
FILE *fp = fopen("/Users/ios/Desktop/1.txt", "a"); //追加
if(fp != NULL ){
char str[] = " shanghai";//数组长度为8
int len = strlen(str); //计算字符串实际长度 只能算得5
for (int i = ; i<len; i++) {
//循环打印每个字符
fputc(str[i], fp); //str[0],str[1],str[2],str[3],str[4]
}
//操作文件
/*
fputc('h', fp);
fputc('e', fp);
fputc('l', fp);
fputc('l', fp);
fputc('o', fp);
*/ //操作完成的提示
printf("完成!"); //关闭
fclose(fp);
}
return ;
}

4、fputs和fgets函数

/*
之前用fgetc和fputc只能一个一个字符的读,或者写,没法一下子读取一串字符串 所以如果要用fgetc或者fputc必须循环读取 所以我们需要一种非常方便读取或者写入一串字符串的方法
fputs: fputs(字符串,文件指针);
作用:写入一串字符串 详解:把字符串写入到文件指针所指向的文件处 例:fputs("我爱上海陆家嘴", fp);
fgets: fgets(char数组地址, n, 文件指针); 作用:读取一串字符串 详解:把读取的字符,存到哪个数组里面,n代表一次读取几个字符,去哪个文件读 注意:1、只能读到n-1个有效字符,因为还有一个字符帮你加'\0'
2、如果读取到换行(\n),那么会停止读取,然后把换行也读取来,并且在换行后面加\0 读取多行:
文件中的文本行数无法确定,所以需要一个循环(死循环)。 判断读取到末尾:
feof(文件指针);
如果返回的是1(真),代表读取到末尾。
如果返回的是0,代表没有到末尾。 */ #include <stdio.h> /**
* 写入一串字符串
*/
void writeString(){
FILE *fp = fopen("/Users/ios/Desktop/1.txt", "w");
if(fp != NULL){
//写字符串
fputs("我爱家乡妹子多", fp);
printf("写完了\n");
fclose(fp);//立即写不要忘关闭,不然内容不会保存
}
} int main(int argc, const char * argv[]) {
FILE *fp = fopen("/Users/ios001/Desktop/1.txt", "r");
if(fp != NULL){
char str[];
//读
while () {
if(feof(fp)){ //如果为真,代表读取到末尾
break; //不需要继续读了,退出循环
}
fgets(str, , fp);
printf("%s",str);
}
/*
fgets(str, 100, fp); //因为你输入10,那么它只会读取99个有效的,还有一个位置是帮你加一个'\0' printf("%s\n",str);
char str2[100];
fgets(str2, 100, fp);
printf("%s\n",str2);
*/
fclose(fp);//关闭文件
}
return ;
}

补充一点:上面的代码判断某个变量是否为NULL的时候  都是 if(fp != NULL){},其实也可以这样写,if(fp){},应为 NULL 就是 0,也就是,当fp不为NULL的时候,就是

4、fread和fwirte函数

/*
fgetc fputc fgets fputs:没有一段一段的读取文件 fread和fwrite就比较像文件流一样一块一块的读或者写 fread:
fread(保存数据的地址,每块的字节大小,读取多少块,文件指针); 1、它是读取文件的,而且任何问题都可以读,而且是分块读取。 1)、因为任何文件都可以读,所以保存数据的地址是可以不同类型。
分块来读:所以要设置每块的字节大小,一共要读取多少块,去哪个文件读 例:
char str[50];
fread(str, 3, 100, fp);
注意:它只关心具体读的字节数,不会关心这些自己里面有没有换行 fwrite:
fwrite(写入的数据,每块的字节大小,写入多少块,文件指针);
它是写入文件的。是分块写入。
第一个是告诉系统,写入什么数据,第二个是告诉系统每块多少字节,第三个是告诉系统分多少块写入,第四个是写入到哪个文件 注意:fwrite不要写的太大,要以实际为准,否则会写很多垃圾的二进制值进去,就打不开了 数组名 == &数组名
*/ #include <stdio.h>
#include <string.h> void testFread(){ FILE *fp = fopen("/Users/ios/Desktop/1.txt", "r"); if(fp){ //操作
while () { //读取大文件时最好分很多段读取,这样可以有效节省内存,所以用循环 if(feof(fp)){ break;
} char str[] = {}; fread(str, , , fp); printf("%s",str); } fclose(fp);
}
} void testFwrite(){ FILE *fp = fopen("/Users/ios/Desktop/1.txt", "w"); if(fp){ /*
char str[] = "好就按我说结婚的撒娇看到过撒娇吧"; int len = strlen(str); fwrite(str, 1, len, fp);
*/ // int num = 97;
//
// fwrite(&num, 4, 1, fp); // char ch = 'a';
//
// fwrite(&ch, 1, 1, fp); char str[] = "10.333"; fwrite(str, ,strlen(str), fp); printf("成功了\n"); fclose(fp); }
} int main(int argc, const char * argv[]) { FILE *fp = fopen("/Users/ios/Desktop/1.txt", "r"); if(fp){ int num;//存的是二进制,打开后会转成十进制的ascii fread(&num, , , fp); printf("%d\n",num); fclose(fp);
} return ;
}

4、fprintf和fscanf函数

/*

 printf:输出到控制台

 scanf: 从控制台输入
scanf("格式化控制符",地址列表); fprintf:输出到文件(写入到文件) fprintf(文件指针,"格式化控制符",参数列表); fscanf:从文件输入(读取) fscanf(文件指针,"格式化控制符",地址列表); */ #include <stdio.h> void testFprintf(){ FILE * fp = fopen("/Users/ios/Desktop/1.txt", "w"); if (fp) { fprintf(fp, "%d",); fclose(fp);
}
} int main(int argc, const char * argv[]) { fprintf(stdout, "哈哈哈哈哈\n"); //跟printf没差别,stdout代表在控制台输出 int num;
fscanf(stdin, "%d",&num); //stdin在控制台输入 printf("num=%d\n",num);
/*
FILE * fp = fopen("/Users/ios/Desktop/1.txt", "r"); if (fp) { // int num;
// char ch;
// fscanf(fp, "%c帅%d",&ch,&num);
// printf("ch=%c num=%d\n",ch,num);//a 99 char str[50] = {0};
char str2[50];
fscanf(fp, "%s\n%s",str,str2); puts(str);
puts(str2);
fclose(fp);
}
*/
return ;
}

四、文件的复制

/*
//加密:
//读取出来以后对每个字节做一个-1的操作
//然后再写,就达到加密的作用了 //解密:
//先读出的加密,然后对每个字节进行+1的操作,然后再写,此时就可以看了 */ #include <stdio.h> int main(int argc, const char * argv[]) { //读取原文件
FILE *fpRead = fopen("/Users/ios/Movies/高清无码声音又好听的片.mp4","r"); //拷贝新的文件
FILE *fpWrite = fopen("/Users/ios/Desktop/123/工作文件不要看.mp4", "w");
if(fpRead){
if(fpWrite){
while(){
if(feof(fpRead)){
break;
} char bytes[*]; //1m
//开始读
fread(bytes, *, , fpRead); //开始写
fwrite(bytes, *, , fpWrite);//写入到这个文件
} printf("做完了!\n");
fclose(fpWrite);
}
fclose(fpRead);
}
return ;
}

c语言学习之基础知识点介绍(十六):文件操作的更多相关文章

  1. c语言学习之基础知识点介绍(六):if和switch结构

    本节主要说c语言中的分支结构. c语言中分支结构有两大类:一种是if,一种是switch. 一.if结构 //if结构,语法: //第一种: if(表达式){ //语句块 } //第二种: if(表达 ...

  2. c语言学习之基础知识点介绍(三):scanf函数

    本节继续介绍c语言的基础知识点. scanf函数:用来接收用户输入的数据. 语法:scanf("格式化控制符",地址列表); 取地址要用到取地址符:&(shift+7) 例 ...

  3. c语言学习之基础知识点介绍(二):格式化控制符和变量的补充

    上节简单介绍了c语言中的一些基础知识点,本节将对之前介绍的不够详细的知识点进行补充. 格式化控制符的消息介绍: %d的其他控制符: 1.%md:m代表这个整数位占用多少位,m是一个整数.实际数字不足的 ...

  4. c语言学习之基础知识点介绍(十四):指针的进阶

    一.指针的加.减法运算 /* 1.加法运算 1).可以跟整数进行加法运算,得到的还是一个地址 公式: 地址 + 1 = 地址 + 1 * 类型所占的字节数 地址 + n = 地址 + n * 类型所占 ...

  5. c语言学习之基础知识点介绍(十):数组

    本节主要介绍数组. 一.数组 /* 数组:一个变量可以存n个变量. 语法:类型 数组名[长度(正整数)]; 例如:int score[5];//定义了一个int类型的数组,长度为5,可以保存5个数据. ...

  6. c语言学习之基础知识点介绍(二十):预处理指令

    一.预处理指令的介绍 预处理命令:在编译之前触发的一系列操作(命令)就叫预处理命令. 特点:以#开头,不要加分号. #include: 文件包含指令 把指定文件的内容复制到相应的位置 #define: ...

  7. c语言学习之基础知识点介绍(十五):函数的指针

    一.函数的指针的介绍 /* 函数指针: 函数的指针,本质上一个指针 指向函数的指针,就是一个函数指针. 回忆:我们写的源代码编译成二进制的指令集,一串交给CPU执行的指令 先存在内存里面,然后CPU读 ...

  8. c语言学习之基础知识点介绍(十二):结构体的介绍

    一.结构体的介绍 /* 语法: struct 结构体名{ 成员列表; }; 切记切记有分号! 说明:成员列表就是指你要保存哪些类型的数据. 注意:上面的语法只是定义一个新的类型,而这个类型叫做结构体类 ...

  9. c语言学习之基础知识点介绍(十):内存空间模型、地址解释及指针变量

    一.内存 /* 内存: 存在内存里的. 内存分了N多个小空间,每个小空间1个字节 每个小空间有它自己的地址.每个地址之间差1 int类型占用4个字节,等于占了4个空间(有4个地址),不需要记住4个地址 ...

  10. c语言学习之基础知识点介绍(十九):内存操作函数

    一.malloc函数 /* 首先需要导入头文件 #include <stdlib.h> malloc void* malloc(n); n是字节大小 开辟堆空间,开辟的字节数以n为准 返回 ...

随机推荐

  1. 安装qc 出现error An error occurred while attempting to connect to the database.

    When trying to install mercury quality center starter edition 9.0 on Windows XP media center, I am g ...

  2. Html笔记(四)图像

    图像标签: <img> <img src="../dir/file" alt="说明文字" height width border/> ...

  3. vijosP1092 全排列

    vijosP1092 全排列 链接:https://vijos.org/p/1092 [思路] 数学+搜索. 根据序号依次确定每一个数. 首先我们可以把未选的数看作一个可选择集合,其次把寻找过程看作一 ...

  4. 洛谷P1120 小木棍

    洛谷1120 小木棍 题目描述 乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过50.     现在,他想把小木棍拼接成原来的样子,但是却忘记了自己开始时有多少根木棍和它们的长 ...

  5. git引用^和~的区别

    这篇git文章必转:解答我一直的疑惑 http://www.cnblogs.com/hutaoer/archive/2013/05/14/3078191.html 一. 引子 在git操作中,我们可以 ...

  6. Android--应用开发1(应用程序框架)

    应用程序的框架,就是所有开发者共同是有和遵循的约定,大家在约定上进行必要的扩展,但程序的主体结构是一致的. Android系统提供给开发者一个框架,我们所有的应用开发就是在这个框架上进行扩展,下来看看 ...

  7. Storm系列(十五)架构分析之Executor-Spout

    Spout实现mk-threads接口用于创建与Executor对应的消息循环主函数. defmulti mk-threads executor-selector Mk-threads函数的主消息循环 ...

  8. HW5.18

    public class Solution { public static void main(String[] args) { System.out.printf("%s\t%s\n&qu ...

  9. Codeforces13C–Sequence(区间DP)

    题目大意 给定一个含有N个数的序列,要求你对一些数减掉或者加上某个值,使得序列变为非递减的,问你加减的值的总和最少是多少? 题解 一个很显然的结果就是,变化后的每一个值肯定是等于原来序列的某个值,因为 ...

  10. POJ2429 - GCD & LCM Inverse(Miller–Rabin+Pollard's rho)

    题目大意 给定两个数a,b的GCD和LCM,要求你求出a+b最小的a,b 题解 GCD(a,b)=G GCD(a/G,b/G)=1 LCM(a/G,b/G)=a/G*b/G=a*b/G^2=L/G 这 ...