1.栈区上的空间运行效率很高
堆区分配的空间一般由程序员主动释放
静态区的话程序运行结束后由系统释放
2.根据数据的组织形式,数据文件被称为文本文件或者二进制文件
数据在内存中以二进制的形式存储,如果不加转换的输出到外存的文件中,就是二进制文件
如果要求在外存上以ASCII码的形式存储,则需要在存储前转换。以ASCII字符的形式存储的文件就是文本文件。
而字符一律以ASCII形式存储,数值型数据既可以用ASCII形式存储,也可以使用二进制形式存储。
3.C语言程序在启动的时候,默认打开了3个流:
stdin-标准输入流,在大多数的环境中从键盘输入,scanf函数就是从标准输入流中读取数据。
stdout-标准输出流,大多数的环境中输出至显示器界面,printf函数就是将信息输出到标准输出流中
stderr- 标准错误流,大多数环境中输出到显示器界面。
这是默认打开了这三个流,我们使用scanf、printf等函数就可以直接进行输入输出操作的。stdin、stdout、stderr 三个流的类型是: FILE*,通常称为文件指针
C语言中,就是通过FILE*的文件指针来维护流的各种操作的。
4.FILE *fopen( const char * filename , const char * mode );
第一个参数是文件名,第二个参数是打开方式
打开方式详细的图搜
fopen函数打开文件失败的话会返回一个空指针
所以在代码FILE* pf = fopen("文件路径","打开方式");后边要加上
if (pf == NULL)
{
perror("fopen");
return 1;
}
5.操作完文件后要记得关闭文件
int fclose( FILE * stream **);**文件
承接上边的代码:
fclose(pf);
pf = NULL;
.表示当前目录
..表示上一级路径
例:
FILE* pf = fopen(".\\..\\exp.txt", "w");//注意这两个参数都得要是""
则会在当前编译器所运行的文件中的上一级文件夹里边打开exp.txt文件
FILE* pf = fopen(".\\..\\..\\exp.txt", "w");
这就在当前编译器所运行的文件中的上一级文件夹的上一级文件夹里边打开exp.txt文件
7.顺序读写函数介绍搜
其中的get是获取信息,即"读",一般参数都是一个:目标文件指针(用"r")
其中的put是写入信息,即"写",一般参数都是两个:"内容",目标文件指针(用"w")
其中的fpintf函数是用来写不同数据类型的数据的
其中的各个函数都可以搜得到
使用示例:
cpp
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
struct stu
{
char name[20];
int age;
float score;
};
int main()
{
struct stu s = { "zhangsan", 18, 99.2f };
FILE* pf = fopen("C:\\Users\\lucke\\Desktop\\data.txt", "w");
if (pf == NULL)
{
perror("fopen");
return 1;
}
fprintf(pf, "%s %d %f", s.name, s.age, s.score);
fclose(pf);
pf = NULL;
return 0;
}
8.注: printf("%f", 99);//输出结果是0.000000
9.二进制写入:
cpp
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
struct stu
{
char name[20];
int age;
float score;
};
int main()
{
struct stu s = { "zhangsan", 18, 99.3f};
FILE* pf = fopen("C:\\Users\\lucke\\Desktop\\data.txt", "wb");
if (pf == NULL)
{
perror("fopen");
return 1;
}
//二进制的形式写进去
fwrite(&s, sizeof(s), 1, pf);
fclose(pf);
pf = NULL;
return 0;
}
写到文本中的是zhangsan 殭艬
因为写进去的是二进制形式,所以要用二进制的形式读出来
cpp
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
struct stu
{
char name[20];
int age;
float score;
};
int main()
{
struct stu s = { 0 };
FILE* pf = fopen("C:\\Users\\lucke\\Desktop\\data.txt", "rb");
if (pf == NULL)
{
perror("fopen");
return 1;
}
//二进制的形式读出来
fread(&s, sizeof(s), 1, pf);
printf("%s %d %f", s.name, s.age, s.score);
fclose(pf);
pf = NULL;
return 0;
}
10.sprintf函数:把格式化的数据转化为字符串
int sprintf( char * buffer , const char * format [, argument ] ... );
使用示例:
cpp
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
struct stu
{
char name[20];
int age;
float score;
};
int main()
{
struct stu s = { "zhangsan" , 18, 89.3f};
char arr[200] = { 0 };
sprintf(arr, "%s %d %f", s.name, s.age, s.score);
printf("%s", arr);
//输出结果是zhangsan 18 89.300003
return 0;
}
sscanf函数:在字符串中读取格式化的数据
int sscanf( const char * buffer , const char * format [, argument ] ... );
使用示例:
cpp
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
struct stu
{
char name[20];
int age;
float score;
};
int main()
{
struct stu s = { "zhangsan" , 18, 89.3f};
struct stu tem = { 0 };
char arr[200] = { 0 };
sprintf(arr, "%s %d %f", s.name, s.age, s.score);
sscanf(arr, "%s %d %f", tem.name, &(tem.age), &(tem.score));
printf("%s %d %f", tem.name, tem.age, tem.score);
//输出结果是:zhangsan 18 89.300003
return 0;
}
换句话说:sprintf函数是将后边的东西转换为字符串并放到第一个参数里边去
sscanf函数是将第一个参数里边的字符串转换为其他形式并放到后边的参数里边去
11.fseek函数可以重新确定文件操作时的光标位置
int fseek( FILE * stream , long offset , int origin );
第一个参数是文件指针,二是偏移量,三是偏移的起始位置
第三个参数有三种选择:
SEEK_SET---------文本的起始位置
SEEK_CUR--------文本现在的光标位置
SEEK_END--------文本的末尾位置
第二个参数可以是负数
使用示例:
文本里边放的是abcdefghi
cpp
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
FILE* pf = fopen("C:\\Users\\lucke\\Desktop\\data.txt", "r");
if (pf == NULL)
{
perror("fopen");
return 1;
}
int ch = 0;
ch = fgetc(pf);
printf("%c\n", ch);
ch = fgetc(pf);
printf("%c\n", ch);
ch = fgetc(pf);
printf("%c\n", ch);
ch = fgetc(pf);
printf("%c\n", ch);
fseek(pf, -4, SEEK_CUR);
ch = fgetc(pf);
printf("%c\n", ch);
ch = fgetc(pf);
printf("%c\n", ch);
/* 输出为a
b
c
d
a
b
*/
fclose(pf);
pf = NULL;
return 0;
}
12.ftell函数返回文件指针相对于起始位置的偏移量
long ftell( FILE * stream );
例:
cpp
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
struct stu
{
char name[20];
int age;
float score;
};
int main()
{
FILE* pf = fopen("C:\\Users\\lucke\\Desktop\\data.txt", "r");
if (pf == NULL)
{
perror("fopen");
return 1;
}
int ch = 0;
ch = fgetc(pf);
printf("%c\n", ch);
ch = fgetc(pf);
printf("%c\n", ch);
ch = fgetc(pf);
printf("%c\n", ch);
ch = fgetc(pf);
printf("%c\n", ch);
int tem = ftell(pf);
printf("%d\n", tem);
//tem打印出来是4
fclose(pf);
pf = NULL;
return 0;
}
13.所谓的偏移量好像就是字节数
14.rewind函数可以将光标移回初始点
void rewind( FILE * stream );
15.feof函数:
feof 的作用:当文件读取结束的时候,判断是读取结束的原因是否是: 遇到文件尾结束。
(1).文本文件读取是否结束,判断返回值是否为 EOF (fgetc),或者 NULL (fgets)
例如:
fgetc判断是否为 EOF(无论是读取到文件末尾还是读取失败,他都会返回EOF)
fgets判断返回值是否为 NULL(无论是读取到文件末尾还是读取失败,他都会返回NULL)
(2).二进制文件的读取结束判断,判断返回值是否小于实际要读的个数。
例如:
fread判断返回值是否小于实际要读的个数。
16.feof函数:在文件读取结束后,判断是否是因为遇到文件末尾而结束(是遇到文件末尾而结束就返回真)
ferror函数:在文件读取结束后,判断是否是因为遇到错误而结束(是遇到错误而结束就返回真)
17.注;
代码if (!NULL):
中的!NULL是真
(因为NULL是0,!0即真)
18.有文件缓冲区这个东西
计算机从内存向磁盘输出的数据会先送到内存中的缓冲区,装满缓冲区后才一起送到磁盘上
从磁盘向计算机输出的数据也会先送到内存中的缓冲区,装满缓冲区后才一起送到目的地上
刷新缓冲区也可以将缓冲区的内容放到目的地中
fflush函数可以刷新缓冲区,fclose函数也有刷新缓冲区的功能