黑马程序员--C语言自学笔记---14static、extern、文件

------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.


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Bright1st

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值