C语言基础 (12) 文件的操作 FILE

  1. 课程回顾

结构体基本操作:

  1. 结构体类型的定义

// struct为关键字 Stu为自定义标识符
// struct Stu才是结构体类型

// 结构体成员不能在定义类型时赋值

struct Stu

{

int
age;

char
name[50];

int score;

} // 后面有分号

2。结构体的定义和初始化

// 结构体变量初始化和数组很类似,只有在定义时,才能初始化

// 定义结构体变量时,别忘了struct关键字

struct Stu obj = {18,”mike”,58}

3。结构体成员变量的使用

obj.age = 18;

(&obj)->age = 18;

2.结构体指针变量

1)       指针变量指向栈区

struct Stu *p = NULL;

struct Stu obj; //栈区结构体

p = &obj; //指向栈区

p ->age = 18;

(*p).age = 18;

2) 指针变量指向堆区

struct Stu *p = NULL;

// 指向堆区

p = (struct Stu *)malloc(sizeof(struct Stu));

p -> age = 18;

free(p);

p = NULL;

3const修饰的指针变量

//看const修饰是*还是变量

const struct Stu *p (代表指针所指向的内存不能变

struct Stu const *p;(代表指针不能变

3.结构体数组

stuct Stu obj[3] = {

{18,”lily”,03},

{18,”lily”,03},

{18,”lily”,03},

}

struct Stu obj2[3] = {18,”lily”,99,22,”lucy”,-80,33….} // 这样就比较不清晰了

struct Stu tmp[3]

int I = 0

for (I = 0;i<3;i++)

{

(tmp +i)->age = 18+I;

(*(tmp+i)).age = 18+I; // .的优先级高,所以要加括号

tmp[i].age = 18+I; //常用

}

4.结构体和函数

1)  同类型结构体变量赋值

struct Stu obj1 = {18,”lily”,99};

struct Stu obj2;

  • obj2 = obj1;

2)函数值传递

a)

struct Stu p;

// 结构体变量本身传递(值传递),形参修改不会影响到实参

// 调用完毕fun()函数,p的成员还是没有赋值

fun(p)

void fun(struct stu p) //值传递,相当于拷贝了一份,所以并没有变

{

p.age = 18;

strcpy(p.name,”mike”);

p.score = 59;

}

C语言基础 (12) 文件的操作 FILE

3 函数地址传递

struct Stu p;

fun(&p);

void fun(struct Stu *p)

{

p->age = 18;

strcpy(p->name,”mike”);

p->score = 59;

}

5 结构体套一级指针

struct stu

{

int age;

char *name; // 一级指针

int score;

}; // 后面有分号

1)  栈区结构体

struct Stu s;

s.age =10;

s.name = (char *)malloc( strlen(“mike”) +1);

strcpy(s.name,”mike”);

s.score = 59;

free(s.name);

2堆区结构体

struct Stu *p; //结构体是指针,后面在堆区分配空间

p = (struct Stu *)malloc(sizeof(struct Stu))

p->name = (char *)malloc(strlen(“mike”)+1)

p->age = 18

strcpy(p->name,”mike”)

p->score = 59

free(p->name)

free(p)

C语言基础 (12) 文件的操作 FILE

枚举

C语言基础 (12) 文件的操作 FILE

typedef

C语言基础 (12) 文件的操作 FILE

#define INT int

宏定义是在预处理阶段,前面的替换后面的

typedef是在编译阶段,后面的替换前面的

2 作业讲解

3 文件概述

C语言基础 (12) 文件的操作 FILE

printf 把内存中的10先放到缓冲区,再放到屏幕

为什么不直接打印到屏幕,而放到缓冲区呢?

为了效率,就是缓存 (可能会拿很多次,

如果只拿一次,当然是直接给屏幕比较快,但是可能会拿很多次

C语言基础 (12) 文件的操作 FILE

C语言基础 (12) 文件的操作 FILE

FILE 所有平台的名字都一样,FILE是一个结构体类型,里面的成员功能一样,不同平台成员的名字不一样

FILE *fp

看一下stdio.h

C语言基础 (12) 文件的操作 FILE

为了兼容改成typedef 最后转成FILE

不同平台成员不一样

(vs2013 vs2015同一个平台不同编译器,里面成员都不一样

FILE所有平台的名字都一样,FILE是一个结构体类型,里面的成员功能一样,不同平台成员的名字不一样

FILE *fp

1、fp指针,只用调用了fopen(),在堆区分配空间,把地址返回给fp

2、fp指针不是指向文件,fp指针和文件关联,fp内部成员保存了文件的状态

char *p

*fp(不能这样写!!不是里面是文件,fp只是保存了文件的状态

C语言基础 (12) 文件的操作 FILE

fd 文件描述符

ulimit

C语言基础 (12) 文件的操作 FILE

1,2被占用了 从3开始

C语言基础 (12) 文件的操作 FILE

C语言基础 (12) 文件的操作 FILE

3、操作fp指针 不能直接操作,必须通过文件库函数来操作fp指针

4、通过库函数操作fp指针,对文件的任何操作,fp内部成员会有相应的变化(操作系统自动完成)

结论:文件的操作是需要操作系统层来支持的,通过文件库函数来操作,不是像普通指针一样,p,*p这样直接拿内容。

https://*.com/questions/5130375/how-exactly-does-fopen-fclose-work

https://www.cnblogs.com/llguanli/p/6791507.html

4 文件分类

C语言基础 (12) 文件的操作 FILE

分为设备文件和磁盘文件

5 文件操作流程

1、  打开文件fopen()

2、  读写文件

a) 按字符读写fgetc(),fputc()

b) 按字符串(行)读取文件fgets(),fputs()

c) 文件结尾判断 feof()          // end of file

3、  关闭文件flose()

6 标准文件设备指针

fp指向堆区一片空间,空间中的数据和硬盘种的关联了

C语言基础 (12) 文件的操作 FILE

文件指针

stdin,stdout,stderr

C语言基础 (12) 文件的操作 FILE

C语言基础 (12) 文件的操作 FILE

C语言基础 (12) 文件的操作 FILE

7 标准设备补充

C语言基础 (12) 文件的操作 FILE

8 文件的打开关闭

C语言基础 (12) 文件的操作 FILE

FILE *fp = NULL;

//1、windows路径写法 因为\是转义字符,所以需要\\

fl = fopen(“D:\\1.txt”,”w”); //windows

fp = fopen(“D:/1.txt”,”w”); //linux,windows

// 当前路径

fp = fopen(“a.txt”,”w”)

fp = fopen(“./a.txt,”w”)

//绝对路径

fp = fopen(“/home/edu/a.txt”,”w”);

fopen会在堆区分配空间,返回堆区地址给fp

C语言基础 (12) 文件的操作 FILE

C语言基础 (12) 文件的操作 FILE

9 文件路径说明

相对路径:

1、在linux,相对路径相对于可执行程序

2、VS

a,编译同时运行程序,相对路径是相对于.vcxproj(项目文件)所在的路径

b, 如果直接运行程序,相对路径线相对于可执行程序

3、Qt

a, 编译同时运行程序,相对路径,相对于debug所在的路径

b, 如果直接运行程序,相对路径相对于可执行程序

fopen(“1.txt”,”w”);

char *p = “1.txt”; //指向文字常量区

fopen(p,”w”);

char p[] = “1.txt” //栈区/数组

fopen(p,”w”); //数组名字是首元素地址

char *mode = “w”;

fopen(“1.txt”,mode);

C语言基础 (12) 文件的操作 FILE

10 上午知识复习

1.文件的类型

文本文件和二进制文件

2.文件的打开关闭

1.文件指针

FILE *fp;

stdin  //0 标准输入

stdout //1 标准输出

stderr //2 标准出错

2.文件的打开

fopen(‘路径’,’权限w/r/a’)

3.文件的关闭

11 fputc的使用

1 打开文件fopen()

2 读写文件

3 关闭文件f close

C语言基础 (12) 文件的操作 FILE

C语言基础 (12) 文件的操作 FILE

12 fputc的使用补充

C语言基础 (12) 文件的操作 FILE

13 fgetc的使用

C语言基础 (12) 文件的操作 FILE

1、如果是文本文件,可以通过-1(EOF) 判断文件是否结尾

(!ASCII码没有-1

C语言基础 (12) 文件的操作 FILE

#include <stdio.h>

#include <string.h>

void write_file()

{

//1、打开文件

FILE *fp = fopen("4.txt", "w");

if (fp == NULL)

{

perror("write_file fopen");

return;

}

//2、写文件

char *p = "abcdef";

int i = 0;

int n = strlen(p);

for (i = 0; i < n; i++)

{

fputc(p[i], fp);

}

//3、关闭文件

fclose(fp);

}

void read_file()

{

//1、打开文件 以读的方式打开

FILE *fp = fopen("4.txt", "r");

if (fp == NULL)

{

perror("write_file fopen");

return;

}

//2、读文件,每次读一个字符

char ch;

// while (ch != -1) //EOF 文本文件结尾默认是-1

while (ch != EOF) // 有这个宏

{

ch = fgetc(fp);

// printf("ch = %c\n", ch); //以char形式打出

printf("ch = %d\n", ch);  //以数字形式打出

}

//3、关闭文件

fclose(fp);

}

int main(int argc, char const *argv[])

{

write_file();

read_file();

return 0;

}

14 feof的存在意义

1、如果是文本文件,可以通过-1(EOF)判断文件是否结尾

2、如果是二进制文件,不能以-1判断文件结尾

3、feof()判断文件是否结尾,任何文件都能判断

C语言基础 (12) 文件的操作 FILE

15 feof的使用

feof(fp) // 如果到文件结尾,返回真

1、如果第一次没有对文件进行读操作,直接调用此函数,永远返回真

2、此函数必须,先读,再调用feof() 才有意义

3、调用此函数,光标不会自动往后移动

4、必须读取后,才能判断是否结束,判断的是读取的字符

C语言基础 (12) 文件的操作 FILE

(这个东西是判断光标以前的字符

C语言基础 (12) 文件的操作 FILE

16 feof的使用补充

C语言基础 (12) 文件的操作 FILE

17 cat命令的实现

将mycat放在cat所在路径

C语言基础 (12) 文件的操作 FILE

C语言基础 (12) 文件的操作 FILE

放到目录里 然后用mycat命令就可以了,C语言的cat命令就是这样实现的

18 课堂答疑

19 vi命令的实现

不能用scanf 因为不能有回车 空格

gets 不能有回车

所以只能用fgets (可以有空格,也可以有回车

C语言基础 (12) 文件的操作 FILE

C语言基础 (12) 文件的操作 FILE

C语言基础 (12) 文件的操作 FILE

// 读一点写一点

20 课堂答疑

C语言基础 (12) 文件的操作 FILE

注意 fgets会保存’\n’

21 fputs的使用

C语言基础 (12) 文件的操作 FILE

22 fgets的使用

C语言基础 (12) 文件的操作 FILE

读一下,发现后面全都是mike

C语言基础 (12) 文件的操作 FILE

因为读到文件结尾的时候会接触本次读取,所以buf内的内容并没有变,还是最后一行的内容,

用一下memset:

C语言基础 (12) 文件的操作 FILE

(边界值的问题,现在也顺便讲解了memset怎么用的

循环读取:

C语言基础 (12) 文件的操作 FILE

解决方法:

C语言基础 (12) 文件的操作 FILE

(放前面

23 作业

上一篇:题解 SP26045 【GCDMAT2 - GCD OF MATRIX (hard)】


下一篇:【企业级框架整合】Springmvc+mybatis+restful+bootstrap框架整合