C&C++学习心法10文件基本读写操作

文件操作

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

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

磁盘文件的分类
计算机的存储在物理上是二进制的,所以物理上所有的磁盘文件本质上都是一样的:以字节为单位进行顺序存储。
在这里插入图片描述

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

  1. 文本文件:基于字符编码的文件
  2. 二进制文件:基于值编码的文件
    文本文件和二进制文件
    1)文本文件
  3. 基于字符编码,常见编码有ASCII、UNICODE等
  4. 一般可以使用文本编辑器直接打开
  5. 数5678的以ASCII存储形式(ASCII码)为: 00110101 00110110 00110111 00111000
    2)二进制文件
  6. 基于值编码,自己根据具体应用,指定某个值是什么意思
  7. 把内存中的数据按其在内存中的存储形式原样输出到磁盘上
  8. 数5678的存储形式(二进制码)为:
  9. 00010110 00101110

文件的打开和关闭

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

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

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

声明FILE结构体类型的信息包含在头文件“stdio.h”中,一般设置一个指向FILE类型变量的指针变量,然后通过它来引用这些FILE类型变量。通过文件指针就可对它所指的文件进行各种操作。
在这里插入图片描述
C语言中有三个特殊的文件指针由系统默认打开,用户无需定义即可直接使用:

  1. stdin: 标准输入,默认为当前终端(键盘),我们使用的scanf、getchar函数默认从此终端获得数据。
  2. stdout:标准输出,默认为当前终端(屏幕),我们使用的printf、puts函数默认输出信息到此终端。
  3. stderr:标准出错,默认为当前终端(屏幕),我们使用的perror函数默认输出信息到此终端。
    文件的打开
    任何文件使用之前必须打开:
#include <stdio.h>
FILE * fopen(const char * filename, const char * mode);
功能:打开文件
参数:
	filename:需要打开的文件名,根据需要加上路径
	mode:打开文件的模式设置
返回值:
	成功:文件指针
	失败:NULL

第一个参数的几种形式:

FILE *fp_passwd = NULL;

	//相对路径:
	//打开当前目录passdw文件:源文件(源程序)所在目录
	FILE *fp_passwd = fopen("passwd.txt", "r");
	
	//打开当前目录(test)下passwd.txt文件
	fp_passwd = fopen(". / test / passwd.txt", "r");
	
	//打开当前目录上一级目录(相对当前目录)passwd.txt文件
	fp_passwd = fopen(".. / passwd.txt", "r");
		
	//绝对路径:
	//打开C盘test目录下一个叫passwd.txt文件
	fp_passwd = fopen("c:/test/passwd.txt","r");

第二个参数的几种形式(打开文件的方式):
在这里插入图片描述
注意:

  • b是二进制模式的意思,b只是在Windows有效,在Linux用r和rb的结果是一样的
  • Unix和Linux下所有的文本文件行都是\n结尾,而Windows所有的文本文件行都是\r\n结尾
  • 在Windows平台下,以“文本”方式打开文件,不加b:
    当读取文件的时候,系统会将所有的 “\r\n” 转换成 “\n”
    当写入文件的时候,系统会将 “\n” 转换成 “\r\n” 写入
    以"二进制"方式打开文件,则读\n写都不会进行这样的转换
    在Unix/Linux平台下,“文本”与“二进制”模式没有区别,"\r\n" 作为两个字符原样输入输出

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

  1. 打开的文件会占用内存资源,如果总是打开不关闭,会消耗很多内存
  2. 一个进程同时打开的文件数是有限制的,超过最大同时打开文件数,再次调用fopen打开文件会失败
  3. 如果没有明确的调用fclose关闭打开的文件,那么程序在退出的时候,操作系统会统一关闭。
#include <stdio.h>
int fclose(FILE * stream);
功能:关闭先前fopen()打开的文件。此动作让缓冲区的数据写入文件中,并释放系统所提供的文件资源。
参数:
	stream:文件指针
返回值:
	成功:0
	失败:-1
#include<stdio.h>

int main()
{
    FILE* fp = fopen("C:\\Users\\Eric\\CLionProjects\\sjlwupo\\data.txt", "r");
    //1、找不到文件
    //2、文件权限(读 写 执行)
    //3、程序打开文件超出上限 65535
    if (fp == NULL)
    {
        printf("打开文件失败\n");
        return -1;
    }
    printf("文件打开成功:%p\n",fp);
    fclose(fp);
    return 0;
}
  • 文件的顺序读 fgetc
#include <stdio.h>
int fgetc(FILE * stream);
功能:从stream指定的文件中读取一个字符
参数:
	stream:文件指针
返回值:
	成功:返回读取到的字符
	失败:-1

#include<stdio.h>

int main()
{
    FILE* fp = fopen("C:\\Users\\Eric\\CLionProjects\\sjlwupo\\data.txt", "r");
    if (!fp)
    {
        printf("文件打开失败\n");
        return -1;
    }

    char ch;
    //文件的字符读取
    //文件默认结尾为-1
    ch = fgetc(fp);
    printf("%c\n", ch);
    //不能修改文件指针  文件在读取时光标流会自动向下移动
    //fp++;//err
    ch = fgetc(fp);
    printf("%c\n", ch);

    //关闭文件
    fclose(fp);

    return 0;
}

调用了两次只能显示两个字符

在这里插入图片描述

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

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

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

在这里插入图片描述

#include<stdio.h>

int main()
{
    FILE* fp = fopen("C:\\Users\\Eric\\CLionProjects\\sjlwupo\\data.txt", "r");
    if (!fp)
        return -1;
    char ch;
    while ((ch = fgetc(fp)) != EOF)
    {
        printf("%c", ch);
    }

    fclose(fp);
    return 0;
}

在这里插入图片描述

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

示例一:写入一个字符

#include<stdio.h>

int main()
{
    FILE* fp = fopen("C:\\Users\\Eric\\CLionProjects\\sjlwupo\\data.txt", "w");
    //以写的方式打开文件 如果文件不存会创建一个新文件  如果文件存在 会清空内容
    if (!fp)
        return -1;

    char ch = 'a';
    //字符写入
    fputc(ch, fp);

    fclose(fp);
    return 0;
}

控制台版本C编译工具

#include<stdio.h>

int main()
{
    FILE* fp = fopen("C:\\Users\\Eric\\CLionProjects\\sjlwupo\\demo3.c", "w");
    if (!fp)
    {
        printf("文件打开失败\n");
        return -1;
    }

    char ch;
    while (1)
    {
        scanf("%c", &ch);
        if (ch == '@')
        {
            break;
        }
        fputc(ch, fp);
    }

    fclose(fp);
    return 0;
}

在这里插入图片描述

按行读写文件

不使用循环读

#include<stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
    FILE* fp = fopen("C:\\Users\\Eric\\CLionProjects\\sjlwupo\\data.txt", "r");
    if (!fp)
        return -1;

    char* p = (char*)malloc(sizeof(char) * 1024);
    memset(p, 0, 5);
    fgets(p, 5, fp);
    printf("%s\n", p);

    memset(p, 0, 5);
    fgets(p, 5, fp);
    printf("%s\n", p);


    free(p);
    fclose(fp);
    return 0;
}

在这里插入图片描述
使用循环读

#include<stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
    FILE* fp = fopen("C:\\Users\\Eric\\CLionProjects\\sjlwupo\\data.txt", "r");

    if (!fp)
        return -1;

    char* p = (char*)malloc(sizeof(char) * 100);

    //feof(文件指针)  判断文件是否到结尾 可以判断文本文件也可以判断二进制文件
    //如果到文件结尾返回值为 非0的值
    //如果没到文件结尾返回值为 0
    while (!feof(fp))
    {
        memset(p, 0, 100);
        fgets(p, 100, fp);

        printf("%s", p);
    }

    free(p);
    fclose(fp);
    return 0;
}

在这里插入图片描述
写文件

#include<stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
    FILE* fp = fopen("C:\\Users\\Eric\\CLionProjects\\sjlwupo\\data.txt", "w");

    if (!fp)
        return -1;

    char ch[] = "hello python and c++";

    fputs(ch, fp);

    fclose(fp);
    return 0;
}

#include<stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
    FILE* fp = fopen("C:\\Users\\Eric\\CLionProjects\\sjlwupo\\data.txt", "w");

    if (!fp)
        return -1;

    char* p = (char*)malloc(sizeof(char) * 1024);

    while (1)
    {
        memset(p, 0, 1024);
        //scanf("%s", p);
        //fgets()
        scanf("%[^\n]", p);
        //吞噬回车\n
        getchar();
        //停止输入命令  comm=exit
        if (!strcmp(p, "comm=exit"))
            break;
        //追加\n
        strcat(p, "\n");
        fputs(p, fp);
    }
    free(p);
    return 0;
}

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值