C语言第十二讲,文件操作.
C语言第十二讲,文件操作.
一丶文件操作概述
在操作系统中,我们的文档都称为文件.操作系统也为我们提供了接口进行操作.不同语言都是使用的相同的接口,只不过封装的上层接口不一样
操作文件的步骤
打开文件->读写文件->关闭文件.
二丶文件流的概述.
文件流称为 输入流和输出流. 其实就是从内存写数据到磁盘.和从磁盘读数据到内存.
内存->磁盘 称为输出流. 输出到磁盘
磁盘->内存 称为输入流.读取到内存.
三丶文件的打开和关闭.
1.操作原型.
FILE *fopen(char *filename, char *mode);
参数1. 我们要打开的文件名. 参数二.我们打开文件的操作方式.
返回值: FILE结构体,这个结构体保存了读取文件的位置,偏移等等各种信息.
例子:
FILE *fp = fopen("D:\\demo.txt","rb");
以rb方式打开.D盘的demo.txt文件.
打开方式 | 说明 |
---|---|
r | 以只读方式打开文件,只允许读取,不允许写入。该文件必须存在。 |
r+ | 以读/写方式打开文件,允许读取和写入。该文件必须存在。 |
rb+ | 以读/写方式打开一个二进制文件,允许读/写数据。 |
rt+ | 以读/写方式打开一个文本文件,允许读和写。 |
w | 以只写方式打开文件,若文件存在则长度清为0,即该文件内容消失,若不存在则创建该文件。 |
w+ | 以读/写方式打开文件,若文件存在则文件长度清为零,即该文件内容会消失。若文件不存在则建立该文件。 |
a | 以追加的方式打开只写文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾,即文件原先的内容会被保留(EOF符保留)。 |
a+ | 以追加方式打开可读/写的文件。若文件不存在,则会建立该文件,如果文件存在,则写入的数据会被加到文件尾后,即文件原先的内容会被保留(原来的EOF符 不保留)。 |
wb | 以只写方式打开或新建一个二进制文件,只允许写数据。 |
wb+ | 以读/写方式打开或建立一个二进制文件,允许读和写。 |
wt+ | 以读/写方式打开或建立一个文本文件,允许读写。 |
at+ | 以读/写方式打开一个文本文件,允许读或在文本末追加数据。 |
ab+ | 以读/写方式打开一个二进制文件,允许读或在文件末追加数据。 |
文件的关闭
int fclose(FILE *fp)
例如:
fclose(fp);
其实fopen本质是调用的Windows API, CreateFile进行操作的.
四丶文件操作之文本操作,字符操作.
文件操作有专门操作文本的一系列函数.
1.从文件中读取一个字符.写入一个字符的函数.
int fgetc (FILE *fp); 从文件中获取一个字符,读取到EOF结尾. EOF不一定是-,不同平台不一样.
end of file 简称EOF 文件结尾.
int fputc ( int ch, FILE *fp );
参数1,写入的字符,参数二,往哪个文件中写(文件指针)
例子:
#include<stdio.h>
int main(){
FILE *fp;
char ch; //如果文件不存在,给出提示并退出
if( (fp=fopen("D:\\demo.txt","rt")) == NULL ){
printf("Cannot open file, press any key to exit!");
getch();
exit();
} //每次读取一个字节,直到读取完毕
while( (ch=fgetc(fp)) != EOF ){
putchar(ch);
}
putchar('\n'); //输出换行符
fclose(fp);
return ;
}
2.EOF注意的问题.读取函数也可能出现EOF错误,此时我们不知道是函数错误,还是真正的到达文件结尾.
所以我们可以使用另外两个函数进行判断.
int feof ( FILE * fp );
int ferror ( FILE *fp );
例子:
#include<stdio.h>
int main(){
FILE *fp;
char ch; //如果文件不存在,给出提示并退出
if( (fp=fopen("D:\\demo.txt","rt")) == NULL ){
printf("Cannot open file, press any key to exit!");
getch();
exit();
} //每次读取一个字节,直到读取完毕
while( (ch=fgetc(fp)) != EOF ){
putchar(ch);
}
putchar('\n'); //输出换行符 if(ferror(fp)){
puts("读取出错");
}else{
puts("读取成功");
} fclose(fp);
return ;
}
五丶文件操作之文本操作,字符串操作
相应的我们可以通过 fgetc和fputc进行字符操作.那么也可以进行字符串操作.一行一行的读.
char *fgets ( char *str, int n, FILE *fp );
参数1,, 数组.
参数2. 读取多少.
参数3.从哪里读取,
我们可以从fp(文件中) 读取参数2个大小.到数组str中.
例子:
#include <stdio.h>
#include <stdlib.h>
#define N 100
int main(){
FILE *fp;
char str[N+];
if( (fp=fopen("d:\\demo.txt","rt")) == NULL ){
printf("Cannot open file, press any key to exit!\n");
getch();
exit();
} while(fgets(str, N, fp) != NULL){
printf("%s", str);
}
fclose(fp);
system("pause");
return ;
}
字符串写入到文件.
int fputs( char *str, FILE *fp );
从数组中写入字符串到fp(文件中);
例子:
#include<stdio.h>
int main(){
FILE *fp;
char str[] = {}, strTemp[];
if( (fp=fopen("D:\\demo.txt", "at+")) == NULL ){
printf("Cannot open file, press any key to exit!\n");
getch();
exit();
}
printf("Input a string:");
gets(strTemp);
strcat(str, "\n");
strcat(str, strTemp);
fputs(str, fp);
fclose(fp);
return ;
}
六丶文件操作之二进制操作(数据块操作)
通常使用上面操作文本文件很简单.但是一般实际编程中都是数据块进行操作.
这样做可以避免很多问题.
数据块操作的函数
size_t fread ( void *ptr, size_t size, size_t count, FILE *fp );
size_t fwrite ( void * ptr, size_t size, size_t count, FILE *fp );
fread是读.fwrite是写.
参数1. ptr,可以是结构体,数组.或者变量.表示我要 读/写. 的内容. 如果是读.则此ptr则是保存数据.如果是写.则次ptr就是写出的数据.
参数2.写出数据的大小. 比如我们有一个变量要写出.我们这个变量的大小就可以定义一下.
参数3.表示我们要写出这个数据块的个数. 可以同时对一个变量/数组/结构体 写出或者读取多次.
参数4.文件指针,表示从哪个文件中读/写.
例子:
#include<stdio.h>
#define N 5
int main(){
//从键盘输入的数据放入a,从文件读取的数据放入b
int a[N], b[N];
int i, size = sizeof(int);
FILE *fp; if( (fp=fopen("D:\\demo.txt", "rb+")) == NULL ){
printf("Cannot open file, press any key to exit!\n");
getch();
exit();
} //从键盘输入数据 并保存到数组a
for(i=; i<N; i++){
scanf("%d", &a[i]);
}
//将数组a的内容写入到文件
fwrite(a, size, N, fp);
//将文件中的位置指针重新定位到文件开头
rewind(fp);
//从文件读取内容并保存到数组b
fread(b, size, N, fp);
//在屏幕上显示数组b的内容
for(i=; i<N; i++){
printf("%d ", b[i]);
}
printf("\n"); fclose(fp);
return ;
}
例子2:
#include<stdio.h> #define N 2 struct stu{
char name[]; //姓名
int num; //学号
int age; //年龄
float score; //成绩
}boya[N], boyb[N], *pa, *pb; int main(){
FILE *fp;
int i;
pa = boya;
pb = boyb;
if( (fp=fopen("d:\\demo.txt", "wb+")) == NULL ){
printf("Cannot open file, press any key to exit!\n");
getch();
exit();
} //从键盘输入数据
printf("Input data:\n");
for(i=; i<N; i++,pa++){
scanf("%s %d %d %f",pa->name, &pa->num,&pa->age, &pa->score);
}
//将数组 boya 的数据写入文件
fwrite(boya, sizeof(struct stu), N, fp);
//将文件指针重置到文件开头
rewind(fp);
//从文件读取数据并保存到数据 boyb
fread(boyb, sizeof(struct stu), N, fp); //输出数组 boyb 中的数据
for(i=; i<N; i++,pb++){
printf("%s %d %d %f\n", pb->name, pb->num, pb->age, pb->score);
}
fclose(fp);
return ;
}
七丶文件操作之格式化读写.
格式化读写就是从文件中.或者从内存中按照指定的格式进行读写.
主要用到两个函数.
int fscanf ( FILE *fp, char * format, ... );
int fprintf ( FILE *fp, char * format, ... );
函数1:
从文件中 按照指定格式化读取.读取到...变量中.
FILE *fp;
int i, j;
char *str, ch;
fscanf(fp, "%d %s", &i, str);
fprintf(fp,"%d %c", j, ch);
函数2:
fprintf同上.只不过作用相反.
操作例子:
#include<stdio.h> #define N 2 struct stu{
char name[];
int num;
int age;
float score;
} boya[N], boyb[N], *pa, *pb; int main(){
FILE *fp;
int i;
pa=boya;
pb=boyb;
if( (fp=fopen("D:\\demo.txt","wt+")) == NULL ){
printf("Cannot open file, press any key exit!");
getch();
exit();
} //从键盘读入数据,保存到boya
printf("Input data:\n");
for(i=; i<N; i++,pa++){
scanf("%s %d %d %f", pa->name, &pa->num, &pa->age, &pa->score);
}
pa = boya;
//将boya中的数据写入到文件
for(i=; i<N; i++,pa++){
fprintf(fp,"%s %d %d %f\n", pa->name, pa->num, pa->age, pa->score);
}
//重置文件指针
rewind(fp);
//从文件中读取数据,保存到boyb
for(i=; i<N; i++,pb++){
fscanf(fp, "%s %d %d %f\n", pb->name, &pb->num, &pb->age, &pb->score);
}
pb=boyb;
//将boyb中的数据输出到显示器
for(i=; i<N; i++,pb++){
printf("%s %d %d %f\n", pb->name, pb->num, pb->age, pb->score);
} fclose(fp);
return ;
}
八丶文件操作之随机读写.
操作文件肯定避免不了我要读取指定文件内容或者写入指定文件内容.
提供了两个函数使用:
void rewind ( FILE *fp ); 函数作用.将文件指针移动到文件头.
int fseek ( FILE *fp, long offset, int origin );函数作用将文件指针移动到指定偏移位置.
相对于origin
起始点 常量名 常量值
文件开头 SEEK_SET
当前位置 SEEK_CUR
文件末尾 SEEK_END
origin值如上.
例子: 移动文件指针到文件开头的位置.100字节
fseek(fp, , SEEK_SET);
获取文件指针位置
long ftell(FILE *stream);
因为我们使用fseek,导致文件指针一直移动.不确定移动到哪里了.所以我们可以使用ftell来获取文件指针位置.
ftell函数的作用可以用来获取文件的大小.
例如:
fseek(fp,0L,SEEK_END); /* 定位到文件末尾 */
flen=ftell(fp); /* 得到文件大小 */
C语言第十二讲,文件操作.的更多相关文章
- PHP(十二)文件操作
- 【阿里聚安全·安全周刊】阿里双11技术十二讲直播预约|AWS S3配置错误曝光NSA陆军机密文件
关键词:阿里双11技术十二讲直播丨雪人计划丨亚马逊AWS S3配置错误丨2018威胁预测丨MacOS漏洞丨智能风控平台MTEE3丨黑客窃取<权利的游戏>剧本|Android 8.1 本 ...
- CG基础教程-陈惟老师十二讲笔记
转自 麽洋TinyOcean:http://www.douban.com/people/Tinyocean/notes?start=50&type=note 因为看了陈惟十二讲视频没有课件,边 ...
- 十一讲/十二讲 最近总是学不进去,这咋办啊 哭了我i我i我i
0: 2,9,7 错错错 帽号回来是列表 1:好像一样? 错错错 不一样,list[0]是一个值,冒号回来是个列表 2:A.insert(0,A[-1]) del A[-1] ...
- Android入门之文件系统操作(二)文件操作相关指令
(一)获取总根 File[] fileList=File.listRoots(); //返回fileList.length为1 //fileList.getAbsolutePath()为"/ ...
- C语言的fopen函数(文件操作/读写)
头文件:#include <stdio.h> fopen()是一个常用的函数,用来以指定的方式打开文件,其原型为: FILE * fopen(const char * path, c ...
- Java笔记(十二) 文件基础技术
文件基础技术 一.文件概述 一)基本概念 1.文件的分类: 1)文本文件:文件中每个二进制字节都是某个可打印字符的一部分.如.java文件 2)二进制文件:文件中每个二进制字节不一定用来表示字符,也可 ...
- C语言程序设计(十三) 文件操作
第十三章 文件操作 文本文件:将数值型数据的每一位数字作为一个字符以其ASCII码的形式存储(每一位数字都单独占用一个字节的存储空间) 二进制文件:数据值是以二进制形式存储的 文本文件可以方便地被其他 ...
- 《Java核心技术卷二》笔记(二)文件操作和内存映射文件
文件操作 上一篇已经总结了流操作,其中也包括文件的读写.文件系统除了读写以为还有很多其他的操作,如复制.移动.删除.目录浏览.属性读写等.在Java7之前,一直使用File类用于文件的操作.Java7 ...
随机推荐
- MySQL开发——【高级操作、五子句】
高级新增操作 ①基本插入操作: insert into 数据表名称(字段) values (值); ②批量插入操作: insert into 数据表名称(字段) values (值1),(值2),(值 ...
- POJ 3107.Godfather 树形dp
Godfather Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 7536 Accepted: 2659 Descrip ...
- Zookeeper系列3 实现分布式锁
基本思路 1 client调用create()方法创建“/locks/_lock_”临时顺序节点,注意节点类型是EPHEMERAL_SEQUENTIAL 2 client调用getChildren(& ...
- 1.5eigen中高级初始化
1.5 高级初始化 这一节讨论一些初始化矩阵的高级方法. 1.The comma initializer eigen提供一个简单设定所有矩阵系数.向量.数组系数的初始化语法,从左上角开始到右下角结束. ...
- Java并发编程:volatile关键字
volatile这个关键字可能很多朋友都听说过,或许也都用过.在Java 5之前,它是一个备受争议的关键字,因为在程序中使用它往往会导致出人意料的结果.在Java 5之后,volatile关键字才得以 ...
- HTTP1.1协议-RFC2616-中文版
转自:http://www.cnblogs.com/k1988/archive/2010/01/12/2165683.html 说明 本文档规定了互联网社区的标准组协议,并需要讨论和建议以便更加完善. ...
- 移植U-Boot时遇到的问题
1. 在lowlevel_init过程中,本来想实现一个串口直接打印字符串的过程,编译的时候出现了问题,说是发现代码执行段没有对齐:“unaligned opcodes detected in exe ...
- verilog HDL-并行语句之assign
线网型数据对象: 是verilog hdl常用数据对象之一,起到电路节点之间的互联作用,类似于电路板上的导线. wire是verilog hdl默认的线网型数据对象. 线网型数据对象的读操作在代码任何 ...
- 几种String对象方法的区别
1.在String对象方法中,发现.slice()方法和.substring()方法的作用几乎相同,都是根据起始索引返回截取得到的字符串.经过查阅资料和实测得到区别: 正常情况下索引都为正值,返回值为 ...
- Linux pwn入门教程(2)——shellcode的使用,原理与变形
作者:Tangerine@SAINTSEC 0×00 shellcode的使用 在上一篇文章中我们学习了怎么使用栈溢出劫持程序的执行流程.为了减少难度,演示和作业题程序里都带有很明显的后门.然而在现实 ...