C基础学习笔记——01-C基础第12天(文件上)

在学习C基础总结了笔记,并分享出来。有问题请及时联系博主:Alliswell_WP,转载请注明出处。

01-C基础第12天(文件上)

目录:
1、文件概述
(1)磁盘文件和设备文件
(2)磁盘文件的分类
(3)文本文件和二进制文件
2、文件的打开和关闭
(1)文件的打开
(2)文件的关闭
(3)按照字符读写文件fgetc、fputc
(4)按照行读写文件fgets、fputs
(5)按照格式化文件fprintf、fscanf

 

1、文件概述

(1)磁盘文件和设备文件
1)磁盘文件
指一组相关数据的有序集合,通常存储在外部介质(如磁盘)上,使用时才调入内存。

2)设备文件
在操作系统中把每一个与主机相连的输入、输出设备看作是一个文件,把它们的输入、输出等同于对磁盘文件的读和写。

(2)磁盘文件的分类
计算机的存储在物理上是二进制的,所以物理上所有的磁盘文件本质上都是一样的:以字节为单位进行顺序存储。

从用户或者操作系统使用的角度(逻辑上)把文件分为:

1)文本文件:基于字符编码的文件  

2)二进制文件:基于值编码的文件

(3)文本文件和二进制文件

1)文本文件
 基于字符编码,常见编码有ASCII、UNICODE等
 一般可以使用文本编辑器直接打开
 数5678的以ASCII存储形式(ASCII码)为:
00110101 00110110 00110111 00111000

2)二进制文件
 基于值编码,自己根据具体应用,指定某个值是什么意思
 把内存中的数据按其在内存中的存储形式原样输出到磁盘上
 数5678的存储形式(二进制码)为:00010110 00101110

2、文件的打开和关闭

在C语言中用一个指针变量指向一个文件,这个指针称为文件指针。

 1 typedef struct
 2 {
 3     short           level;    //缓冲区"满"或者"空"的程度 
 4     unsigned        flags;    //文件状态标志 
 5     char            fd;        //文件描述符
 6     unsigned char   hold;    //如无缓冲区不读取字符
 7     short           bsize;    //缓冲区的大小
 8     unsigned char   *buffer;//数据缓冲区的位置 
 9     unsigned        ar;     //指针,当前的指向 
10     unsigned        istemp;    //临时文件,指示器
11     short           token;    //用于有效性的检查 
12 }FILE;

 

FILE是系统使用typedef定义出来的有关文件信息的一种结构体类型,结构中含有文件名、文件状态和文件当前位置等信息。

声明FILE结构体类型的信息包含在头文件“stdio.h”中,一般设置一个指向FILE类型变量的指针变量,然后通过它来引用这些FILE类型变量。通过文件指针就可对它所指的文件进行各种操作。

 

C语言中有三个特殊的文件指针由系统默认打开,用户无需定义即可直接使用:
1)stdin: 标准输入,默认为当前终端(键盘),我们使用的scanf、getchar函数默认从此终端获得数据。
2)stdout:标准输出,默认为当前终端(屏幕),我们使用的printf、puts函数默认输出信息到此终端。
3)stderr:标准出错,默认为当前终端(屏幕),我们使用的perror函数默认输出信息到此终端。

(1)文件的打开

 任何文件使用之前必须打开

1 #include <stdio.h>
2 FILE * fopen(const char * filename, const char * mode);
3 功能:打开文件
4 参数:
5     filename:需要打开的文件名,根据需要加上路径
6     mode:打开文件的模式设置
7 返回值:
8     成功:文件指针
9     失败:NULL

第一个参数的几种形式

 1     FILE *fp_passwd = NULL;
 2 
 3     //相对路径:
 4     //打开当前目录passdw文件:源文件(源程序)所在目录
 5     FILE *fp_passwd = fopen("passwd.txt", "r");
 6     
 7     //打开当前目录(test)下passwd.txt文件
 8     fp_passwd = fopen(". / test / passwd.txt", "r");
 9     
10     //打开当前目录上一级目录(相对当前目录)passwd.txt文件
11     fp_passwd = fopen(".. / passwd.txt", "r");
12         
13     //绝对路径:
14     //打开C盘test目录下一个叫passwd.txt文件
15     fp_passwd = fopen("c://test//passwd.txt","r");

注意:

1)b是二进制模式的意思,b只是在Windows有效,在Linux用r和rb的结果是一样的

2)Unix和Linux下所有的文本文件行都是\n结尾,而Windows所有的文本文件行都是\r\n结尾

3)在Windows平台下,以“文本”方式打开文件,不加b:
  当读取文件的时候,系统会将所有的 "\r\n" 转换成 "\n"
  当写入文件的时候,系统会将 "\n" 转换成 "\r\n" 写入
  以"二进制"方式打开文件,则读\写都不会进行这样的转换

4)在Unix/Linux平台下,“文本”与“二进制”模式没有区别,"\r\n" 作为两个字符原样输入输出

(2)文件的关闭

任何文件在使用后应该关闭:

1)打开的文件会占用内存资源,如果总是打开不关闭,会消耗很多内存

2)一个进程同时打开的文件数是有限制的,超过最大同时打开文件数,再次调用fopen打开文件会失败

3)如果没有明确的调用fclose关闭打开的文件,那么程序在退出的时候,操作系统会统一关闭。

1 #include <stdio.h>
2 int fclose(FILE * stream);
3 功能:关闭先前fopen()打开的文件。此动作让缓冲区的数据写入文件中,并释放系统所提供的文件资源。
4 参数:
5     stream:文件指针
6 返回值:
7     成功:0
8     失败:-1

 

(3)按照字符读写文件fgetc、fputc

1)写文件

1 #include <stdio.h>
2 int fputc(int ch, FILE * stream);
3 功能:将ch转换为unsigned char后写入stream指定的文件中
4 参数:
5     ch:需要写入文件的字符
6     stream:文件指针
7 返回值:
8     成功:成功写入文件的字符
9     失败:返回-1

 

2)文件结尾

在C语言中,EOF表示文件结束符(end of file)。在while循环中以EOF作为文件结束标志,这种以EOF作为文件结束标志的文件,必须是文本文件。在文本文件中,数据都是以字符的ASCII代码值的形式存放。我们知道,ASCII代码值的范围是0~127,不可能出现-1,因此可以用EOF作为文件结束标志。

 

当把数据以二进制形式存放到文件中时,就会有-1值的出现,因此不能采用EOF作为二进制文件的结束标志。为解决这一个问题,ANSI C提供一个feof函数,用来判断文件是否结束。feof函数既可用以判断二进制文件又可用以判断文本文件。

1 #include <stdio.h>
2 int feof(FILE * stream);
3 功能:检测是否读取到了文件结尾。判断的是最后一次“读操作的内容”,不是当前位置内容(上一个内容)。
4 参数:
5     stream:文件指针
6 返回值:
7     非0值:已经到文件结尾
8     0:没有到文件结尾

3)读文件

1 #include <stdio.h>
2 int fgetc(FILE * stream);
3 功能:从stream指定的文件中读取一个字符
4 参数:
5     stream:文件指针
6 返回值:
7     成功:返回读取到的字符
8     失败:-1

 

4)练习:实现vi、cat

C语言实现vi命令

#include<stdio.h>
#include<string.h>
int main(int argc, char **args)
{
    if(argc < 2)
        return 0;
    FILE *fp=fopen(args[1],"w");
    char buf[1024];
    while(1)
    {
        //int i=0;
        fgets(buf,sizeof(buf),stdin);
        if(strncmp(buf,":wq",3)==0)
        {
            break;
        }
         fputs(buf,fp);
    /*while(buf[i]!='\0')
    {
        fputc(buf[i],fp);
        i++;
    }*/   //另一种将数组内容传入文件指针指向文件的方法
    }

    fclose(fp);
    
    return 0;
}

C语言实现cat命令

法一:

#include<stdio.h>
#include<string.h>
int main(int argc, char **args)
{
    if(argc < 2)
        return 0;
    FILE *fp=fopen(args[1],"r");
    char ch;
    while(!feof(fp))
    {
        ch=fgetc(fp);
        if(feof(fp))
        {
            break;
        }
        printf("%c",ch);
    }
    fclose(fp);
    return 0;
}

法二:

#include<stdio.h>
#include<string.h>
int main(int argc, char **args)
{
    if(argc < 2)
        return 0;
    FILE *fp=fopen(args[1],"r");
    char buf[100];
    while (!feof(fp)) //文件没有结束
    {
        memset(buf, 0, sizeof(buf));
        char *p = fgets(buf, sizeof(buf), fp);
        if (p != NULL)
        {
            printf("%s", buf);
        }
    }
    fclose(fp);
    return 0;
}

 

(4)按照行读写文件fgets、fputs

1)写文件

1 #include <stdio.h>
2 int fputs(const char * str, FILE * stream);
3 功能:将str所指定的字符串写入到stream指定的文件中,字符串结束符 '\0'  不写入文件。 
4 参数:
5     str:字符串
6     stream:文件指针
7 返回值:
8     成功:0
9     失败:-1

2)读文件

 1 #include <stdio.h>
 2 char * fgets(char * str, int size, FILE * stream);
 3 功能:从stream指定的文件内读入字符,保存到str所指定的内存空间,直到出现换行字符、读到文件结尾或是已读了size - 1个字符为止,最后会自动加上字符 '\0' 作为字符串结束。
 4 参数:
 5     str:字符串
 6     size:指定最大读取字符串的长度(size - 1 7     stream:文件指针
 8 返回值:
 9     成功:成功读取的字符串
10     读到文件尾或出错: NULL

3)强化训练:文件版四则运算

有个文件大小不确定,每行内容都是一个四则运算表达式,还没有算出结果,写一个程序,自动算出其结果后修改文件。

 (5)按照格式化文件fprintf、fscanf

1)写文件

1 #include <stdio.h>
2 int fprintf(FILE * stream, const char * format, ...);
3 功能:根据参数format字符串来转换并格式化数据,然后将结果输出到stream指定的文件中,指定出现字符串结束符 '\0'  为止。
4 参数:
5     stream:已经打开的文件
6     format:字符串格式,用法和printf()一样
7 返回值:
8     成功:实际写入文件的字符个数
9     失败:-1

2)读文件

1 #include <stdio.h>
2 int fscanf(FILE * stream, const char * format, ...);
3 功能:从stream指定的文件读取字符串,并根据参数format字符串来转换并格式化数据。
4 参数:
5     stream:已经打开的文件
6     format:字符串格式,用法和scanf()一样
7 返回值:
8     成功:参数数目,成功转换的值的个数
9     失败: - 1

3)强化训练:文件版排序

 

 

 

在学习C基础总结了笔记,并分享出来。有问题请及时联系博主:Alliswell_WP,转载请注明出处。

posted on 2020-06-03 14:50  Alliswell_WP  阅读(223)  评论(0编辑  收藏  举报

导航