------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
1. static和extern
1) 两个都是用来修饰变量的(局部的static实际也是全局的)
2) static修饰的变量,只有包含那个变量定义 的源代码文件可以访问(内部的变量)
3) extern定义的变量,所有源文件都可以访问,只要声明了就可以。(外部变量)
4) static定义的变量的作用域会得到延长
5) static定义变量的语句只会被执行一次
6) extern不能修饰局部变量
7) 对全局变量的作用
① static修饰的全局变量(内部变量),表示该全局变量只能在当前文件中使用,而不能在其他文件中使用。可以在不同文件中声明同名变量。
② extern修饰的全局变量,表示该变量可以在当前文件中使用,也可以在其他文件中使用。
③ extern在两个文件中不能声明同名变量(两个文件有包含关系)
8) 修饰函数
① static修饰的函数,是一个内部函数,只能在定义的文件中使用
② extern声明的函数,可以在定义文件中使用, 也可以在其他文件中使用。可以在定义文件中声明,也可以在调用之前来声明,而且extern也可以省略。
文件
1. 文件指存储在外部介质上数据的集合,这个数据集有一个名称,叫做文件名。
2. Ascii码文件和二进制文件
1) ASCII文件也叫文本文件,是把每一个字符先找到其ASCII码,然后用二进制的一个字节进行存储
2) 二进制文件是指按二进制的编码方式来存放的。
3. 文件操作步骤及原理
1) 对文件的操作步骤
① 引入头文件(stdio.h)
② 定义文件指针
③ 打开文件
④ 文件读写
⑤ 关闭文件
2) 对文件读写的函数
① 字符读写函数
② 字符串读写函数
③ 数据块读写函数
④ 格式化读写函数
3) 文件操作原理
文件缓冲区:当对文件进行读写时,会把数据先放到缓冲区中,然后从缓冲区中读取数据。
4. C语言文件指针
1) 在C语言中,用一个指针变量指向一个文件,这个指针称为文件指针。
2) 定义文件指针FILE *fp;
5. 文件的打开和关闭
1) 文件打开,使用fopen函数,调用形式为
文件指针变量名 = fopen(文件名,使用文件方式);
FILE*fp = NULL;
fp =fopen(“a.txt”,”r”);//打开当前目录下的a.txt文件,且只能进行读操作,不能修改文件。
2) 关闭文件,使用fclose函数,调用形式为
fclose(文件指针);
fclose(fp);//成功关闭文件,返回值为0,非0则关闭失败。
注意:如果文件写操作时,没有进行关闭,可能会导致文件写入失败。
6. 文件使用方式
注意事项:
1) 凡是以“r”打开的文件,该文件必须存在,且只能从该文件读出。
2) 用“w”打开的文件只能向该文件写入。若打开的文件不存在,则以指定的文件名建立该文件,若打开的文件已经存在,则将该文件删去,重建一个新文件。
3) 若要向一个已存在的文件追加信息,只能用”a”方式打开文件。如果文件不存在,也会自动帮我们创建。
4) 再打开一个文件时,如果出错,fopen将返回一个空指针值NULL。在程序中可以用这一信息来判别是否完成打开文件的工作,并做相应的处理。
5) 把一个文本文件读入内存时,要将ASCII码转换成二进制码,而把文件以文本方式写入磁盘时,也要把二进制转换成ASCII码,因此文本文件的读写要花费较多的转换时间。对二进制文件的读写不存在这种转换。
6) 标准输入文件(键盘),标准输出文件(显示器),标准出错输(出错信息)是由系统打开的,可直接使用。
7. 字符读写函数
字符读写函数是以字符(字节)为单位的读写函数。每次可从文件读出或向文件写入一个字符。
1) 字符写入函数fputc
fputc函数的功能是把一个字符写入指定的文件中。函数调用形式为:fputc(字符,文件指针);字符可以是字符变量或常量。
2) 字符读取函数fgetc
从文件中读取一个字符到变量中。调用形式为:fgetc(文件指针);
#include<stdio.h>
#include<string.h>
intmain(int argc, const char * argv[]) {
//定义文件指针
FILE *fp = NULL;
char str[] = "I LOVE YOU!";
//打开文件
fp = fopen("a.txt","rw");
//判断是否打开成功
if (fp!=NULL) {
printf("文件打开成功!\n");
//写入文件
for (int i=0; i<strlen(str); i++) {
fputc(str[i], fp);
}
char ch = fgetc(fp);
//EOF是文件末尾的标志。
//读文件
while (ch!=EOF) {
//输出字符
putchar(ch);
ch = fgetc(fp);
}
printf("\n");
}else{
printf("文件打开失败!\n");
return 0;
}
fclose(fp);
return 0;
}
3) 从键盘接收一个字符串,写入到文件中去
#include<stdio.h>
intmain(int argc, const char * argv[]) {
//定义变量
char ch;
int count;
//打开文件
FILE *fp = fopen("b.txt","w+");
//如果打开成功,先写入文件
if(fp!=NULL){
//提示用户输入
printf("请输入一个字符串:\n");
//接收字符串
ch = getchar();
while (ch!='\n') {
fputc(ch, fp);
//记录输入字符个数
count++;
ch = getchar();
}
printf("一共输入了%d个字符\n",count);
rewind(fp);//让文件指针重新指向文件开头
//读取文件
ch = fgetc(fp);
while (ch!=EOF) {
putchar(ch);
ch = fgetc(fp);
}
printf("\n");
}
fclose(fp);
return 0;
}
8. 字符串读写函数
1) 字符串写入函数fputs
fputs函数的功能是向指定的文件写入一个字符串,调用形式为
fputs(字符串,文件指针);
字符串可以是字符串常量,也可以是字符数组名或指针变量。
2) 字符串读取函数fgets
fgets函数的功能是从文件中读取出一个字符串,调用形式为
fgets(数组名,字节数,文件指针);
数组是用来保存从文件中读取出的字符串,字节数是每次读取的字符串的长度。
#include<stdio.h>
intmain(int argc, const char * argv[]) {
//写入字符串到文件中
char str[] = "welcome to China!";
//定义变量
//定义文件指针,打开文件
FILE *fp = fopen("str.txt","w+");
//判断
char str2[100];
int count = 0;
if (fp!=NULL) {
//写入到文件中
count = fputs(str, fp);//返回写入的字符串的长度
printf("当前写入字符个数为:%d\n",count);
//从文件中读取字符串
//fgets读取的时候,当文件内容读取完毕后,会给字符串加
上结束符\0
//fgets读取的时候,遇到\n或EOF,读取完毕。
rewind(fp);
fgets(str2, sizeof(str2), fp);
printf("%s\n",str2);
}
fclose(fp);
return 0;
}
9. 查看文本文件内容
文本文件也叫ASCII码文件,是根据保存的字符找到其对应的ASCII码,然后把各自的ASCII码转化成二进制以十六进制进行存储。
查看方法:比如要查看a.txt的内容,可把a.txt先拷贝到main.c目录,直接拖拽到target,右击a.txt选择open as,再选择HEX,就可以查看其16进制的保存形式了。
10. 数据块读写函数
1) 读数据块函数:fread(buffer,size,count,fp);
buffer要保存结果的数组,size为每块的大小,count为要读的块数,fp为文件指针。
表示为从fp指向的文件中读取内容,共读取count块,每块大小为size,把读取的内容保存到buffer中去。
2) 写数据块函数:fwrite(buffer,size,count,fp);
buffer为数组。把数组中的元素读取出来,保存到文件中去,每次读取count块,每块大小为size。
#include<stdio.h>
int main(int argc, const char* argv[]) {
//定义文件指针打开文件
FILE *fp = fopen("a.txt", "w+");
//判断
if(fp!=NULL){
charstr[]="I LOVE";
char str2[20];
//用fwrite写一个数据块
fwrite(str, sizeof(str), 1, fp);
printf("写入成功!\n");
rewind(fp);//让文件指针重新指向文件开头
//用fread读取一个数据块
fread(str2, sizeof(str2), 1, fp);
printf("%s\n",str2);
}
fclose(fp);
return 0;
}
3) 从文件中读写结构体信息
#include <stdio.h>
struct Student{
char name[20];
int age;
int score;
};
int main(int argc, const char * argv[]) {
//先定义一个结构体数组
struct Student stu[3]={{"老大",54,89},{"老二",35,78},{"
老三",27,70}};
//定义文件指针并打开文件
FILE *fp = fopen("stu.data", "wb+");
//判断
if (fp!=NULL) {
//循环写入到文件
for (int i=0; i<3; i++) {
fwrite(&stu[i], sizeof(struct Student), 1,
fp);
}
printf("写入成功!\n");
//调整文件指针
rewind(fp);
//读文件
//先定义一个用来存取数据的结构体数组
struct Student stu2[3];
//循环读文件内容
for (int i=0; i<3; i++) {
fread(&stu2[i], sizeof(struct Student), 1,
fp);
}
//输出文件内容
for (int i=0; i<3; i++) {
printf("姓名:%s,年龄:%d,成绩:%d\n",stu2
[i].name,stu[i].age,stu[i].score);
}
}
fclose(fp);
return 0;
}
11. 格式化读写函数
1) 调用格式为:
fscanf(文件指针,格式字符串,输入表列);按格式字符串的格式把输入表列的数据输入到文件中去。
fprintf(fp,”%d##%d”,a,b);
fprintf(文件指针,格式字符串,输出表列);
fscanf(fp,”%d##%d”,&m,&n);
按格式字符串的格式,从文件中读取数据,并把对应变量的值保存到输出表列的变量中。
2) 格式化读写一个二维数组
使用fprintf和fscanf函数将一个二维数组逐行写入到文件中,并读取出来,格式为:
1,2#
3,4#
5,6#
#include<stdio.h>
intmain(int argc, const char * argv[]) {
//定义数组
int a[3][2]={1,2,3,4,5,6};
//定义文件指针,打开文件
FILE *fp = fopen("a.txt","rw+");
//判断
if (fp!=NULL) {
//写入文件
for (int i=0; i<3; i++) {
fprintf(fp,"%d,%d#\n",a[i][0],a[i][1]);
}
printf("写入成功!\n");
//读文件
int arr[3][2];
for (int i=0; i<3; i++) {
fscanf(fp,"%d,%d#\n",&arr[i][0],&arr[i][1]);
}
//输出内容
for (int i=0; i<3; i++) {
for (int j=0; j<2; j++) {
printf("%d\t",a[i][j]);
}
putchar('\n');
}
}
fclose(fp);
return 0;
}
12. 文件的随机读写
1) 文件定位
① 实现随机读写的关键是要按要求移动位置指针,这称为文件的定位。
② 移动文件内部位置指针的函数主要有两个,即rewind()和fseek()
调用格式为:rewind(文件指针);把文件指针移到文件开头。
fseek(文件指针,位移量,起始点);
重点介绍fseek函数
文件指针:指向被移动的文件。
位移量:表示移动的字节数,要求位移量是long型数据,以便在文件长度大于64KB时不会出错。当用常量表示位移量时,要求加后缀”L”。
起始点:表示从何处开始计算位移量,规定的起点有三种:文件首,当前位置和文件尾。
例如:fseek(fp,100L,0 );表示把位置指针移到离文件首100个字节处。
还要说明的是fseek函数一般用于二进制文件。在文本文件中由于要进行转换,故往往计算的位置会出现错误。
2) 文件的随机读写。
#include<stdio.h>
structStudent{
char name[20];
int age;
int score;
};
intmain(int argc, const char * argv[]) {
//读取stu.data中的第二个学生的信息
//定义文件指针,打开文件
FILE *fp = fopen("stu.data","r");
//判断
if (fp!=NULL) {
//读取文件(只读取第二个学生的信息)
struct Student stu;
//进行文件定位
fseek(fp, sizeof(struct Student)*2,SEEK_SET);
//读文件
fread(&stu, sizeof(struct Student),1, fp);
//显示学生信息
printf("姓名:%s,年龄:%d,成绩:%d
\n",stu.name,stu.age,stu.score);
}
fclose(fp);
return 0;
}
13. 文件检测函数
1) 文件结束检测函数feof()
feof(文件指针)
判断文件是否处于文件结束位置,如文件结束,则返回值为1,否则为0;
这个函数总是多执行一次。不建议经常使用,可使用EOF来判断是否到文件结尾。
2) 读写文件出错检测函数ferror()
Ferror(文件指针);
检查文件在用各种输入输出函数进行读写时是否出错。如ferror返回值为0表示未出错,否则表示有错。
3) 文件出错标志和文件结束标志置0函数。
clearerr(文件指针);
本函数用于清除出错标志和文件结束标志,使它们的值为0.