C语言基础语法第十二篇

文件操作

1.C语言中的文件是什么?

所谓文件一般是指储存在外部介质上的数据集合,比如txt,bmp,jpg,exe,rmvb等

这些文件各有各的用途,我们通常将他们存放在磁盘或者可移动盘(U盘)等介质中

文件是一段数据的集合,这些数据可以是有规则的集合,也可以是无序的集合。操作系统也是以文件为单位对数据进行管理的。也就是说,要访问外部介质上的数据,必须先按照文件名查找,然后从该文件中读取数据。要想写入数据到外部介质,必须得建立一个文件,然后再写入。因此,眼前的文件只是数据的集合

2.文件三要素:文件路径,文件名,后缀

由于C语言中'\'一般是转义字符的起始标志,故在路径中需要用两个'\'表示路径中目录层次的间隔,也可以使用'/'作为路径的分隔符

例如:"F:\\LoveHoneyYou_FILE\\test.c"或者"F:/LoveHoneyYou_FILE/test.c",表示文件test.c保存在F盘LoveHoneyYou_FILE目录下

文件路径:可以显示指出其绝对路径,如上面的 " F:\\ " 或者 " F:/"等

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>

int main()
{
	FILE*fp = fopen("F:F:\1\LoveHoneyYou_FILE\LoveHoneyYou_FILE\\LoveHoneyYou.txt", "w");
	if (NULL == fp)
	{
		printf("打开失败!!\n");
		exit(1);
	}
	fclose(fp);
	fp = NULL;
	system("pause");
	return 0;
}

 

 

如果没有显示指出其路径,则为默认为当前路径,也就是相对路径

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>

int main()
{
	FILE*fp = fopen("LoveHoneyYou.txt", "w");
	if (NULL == fp)
	{
		printf("打开失败!!\n");
		exit(1);
	}
	fclose(fp);
	fp = NULL;
	system("pause");
	return 0;
}

 

数据的输入和输出几乎便随着每个C语言程序,所谓输入就是从"源端"获取数据,所谓输出可以理解为向"终端"写入数据。这里的源端可以是键盘,鼠标,硬盘,光盘,扫描仪等输入设备,终端可以是显示器,硬盘,打印机等输出设备。在C语言中,把这些输入和输出设备也看作"文件"

(才开始学总是会分不清方向----可简单的理解为,数据要从程序向外流出,就是输出;数据从别的地方需要流入程序就是输入。要有坚定的信仰,站在程序的角度出发)

3.预定义标准流

stdin 与标准输入流关联的FILE*类型表达式

stdout 与标准输出流关联的FILE*类型表达式

stderr 与标准错误输出流关联的FILE*类型表达式

4.流的概念和分类

标准C的I/O系统即标准I/O系统,把任意输入的源端或任意输出的终端,都抽象成了概念上的"标准I\O设备"或称"标准逻辑设备"。程序绕过具体设备,直接与该"逻辑设备"进行交互,这样就为程序设计者提供了一个不依赖于任何具体I\O设备的统一操作接口,通常把抽象出来的"标准逻辑设备"或"标准文件"称作"流"

把任意I\O设备,转换成逻辑意义上的标准I\O设备或者标准文件的过程,并不需要程序设计者感知和处理,是由标准I\O系统自动完成的。在这个意义上,可认为任意输入的源端和输出的终端均对应一个"流"

1) 流按流行分为:输入流和输出流。从文件获取数据的流称为输入流,向文件输出数据称为输出流

2) 流按数据形式分为:文本流和二进制流。文本流是ASC||码字符序列,而二进制流是字节序列

3) 流是一种抽象概念,负责在数据的产生者和数据的使用者之间建立关系,并且管理数据的流动

5.二进制文件和文本文件的区别

根据数据的组织形式不同,可以把文件分为:文本文件和二进制文件

文本文件:把要存储的数据当成一系列字符组成,把每个字符的ASC||码值存入文件中。每个ASC||码值占一个字节,每个字节表示一个字符。所以文本文件也称字符文件,或ASC||文件,是字符序列文件。

写入:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>

int main()
{
	FILE*fp = fopen("Test.txt", "w");
	if (fp == NULL)
	{
		exit(1);
	}
	int arr[] = { 12, 23, 34, 45, 56, 67, 78, 89, 90, 100 };
	char buff[256] = { 0 };
	int len = 0;
	for (int i = 0; i < 10; i++)
	{
		fprintf(fp, "   %4d", arr[i]);                //写入文件
		fprintf(stdout, "  %4d", arr[i]);             //输出到屏幕
		len += sprintf(buff+len, "  %4d", arr[i]);    //写入到buff缓冲区
	}
	fclose(fp);
	fp = NULL;
	system("pause");
	return 0;
}

在内存中: 

 

读取:

#include <stdio.h>
#include <stdlib.h>

#define N 10

int main()
{
	int arr[N] = { 0 };
	FILE*fp = fopen("Test.txt", "r");
	if (fp == NULL)
	{
		exit(1);
	}
	for (int i = 0; i < N; i++)
	{
		fscanf(fp,"%d", &arr[i]);
	}
	fclose(fp);
	fp = NULL;
	system("pause");
	return 0;
}

注:

在读取文件时,执行完此语句

会将fp和对应的磁盘文件关联起来 

执行完这条语句

会一把将磁盘内对应文件的数据全部读入文件流缓冲区 ,我们打开内存观察

 我们是通过循环一个一个的从缓冲区中取数据(字符),读取时会根据相应的格式将字符转换为需要的数据类型的数据

把结构体类型写以文本形式写入文件

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
struct Student
{
	char id[20];
	char name[20];
	char sex[8];
	int age;
};
int main()
{
	struct Student s = { "2020032562", "LoveHoneyYou", "MAN", 20 };
	FILE*fp = fopen("Student_Infor.txt", "w");
	if (fp == NULL)
	{
		printf("打开失败!\n");
		exit(1);
	}
	fprintf(fp, "%s\n", s.id);
	fprintf(fp, "%s\n", s.name);
	fprintf(fp, "%s\n", s.sex);
	fprintf(fp, "%d\n", s.age);
	fclose(fp);
	fp = NULL;
	system("pause");
	return 0;
}

 读取:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>

struct Student
{
	char id[20];
	char name[20];
	char sex[8];
	int age;
};

int main()
{
	struct Student s = { 0 };
	FILE*fp = fopen("Student_Infor.txt", "r");
	if (fp == NULL)
	{
		exit(1);
	}
	fscanf(fp, "%s", s.id);
	fscanf(fp, "%s", s.name);
	fscanf(fp, "%s", s.sex);
	fscanf(fp, "%d", &s.id);
	fclose(fp);
	fp = NULL;
	system("pause");
	return 0;
}

在读取时,要按照文件存放数据的顺序读取,不然就可能出现,s的姓名里却放的是其学号,诸如此类的问题 

二进制文件:把数据对应的二进制形式存储到文件中,是字节序列文件

二进制文件写入函数:size_t  fwrite  (const  void * ptr,size_t  count ,FILE * stream)

函数参数

ptr:这是指向要被写入元素的数组的指针

size:这是要被写入的每个元素的大小,以字节为单位

count:这是元素个数,每个元素的大小为size个字节

stream:这是指向FILE对象的指针,该FILE对象指定了一个输出流

返回写入成功元素的个数,若出现错误或到达文件末尾,则可能小于count

若返回的数值与count的数值不同,则写入错误将阻止函数完成。

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>

int main()
{
	int arr[] = { 12, 23, 34, 45, 56, 67, 78, 89, 90, 100 };
	int len = sizeof(arr) / sizeof(arr[0]);
	FILE*fp = fopen("Bin_File.txt", "wb");
	if (fp == NULL)
	{
		printf("打开失败!\n");
		exit(1);
	}
	fwrite(arr, sizeof(arr[0]), len, fp);
	fclose(fp);
	fp = NULL;
	system("pause");
	return 0;
}

为什么在文本中显示是乱码呢? 

在文本中显示时, 会将磁盘文件中的二进制数据,以字节为单位,显示成一个一个的字符

 

   注:注意光标位置 

文件流中内存显示:

 结构体类型数据以二进制写入文件

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>

struct Student
{
	char id[20];
	char name[20];
	char sex[8];
	int age;
};

int main()
{
	struct Student s1 = { "2020032562", "LoveHoneyYou", "MAN", 20 };
	FILE*fp = fopen("Bin_student.txt", "wb");
	if (fp == NULL)
	{
		printf("打开失败!\n");
		exit(1);
	}
	fwrite(&s1, sizeof(struct Student), 1, fp);
	fclose(fp);
	fp = NULL;
	system("pause");
	return 0;
}

块数据读取函数:size_t fread (void * ptr ,size_t  size ,size_t   count,FILE * stream )

函数参数

ptr:指向大小至少为(size*count) 字节的内存块,从流中读取的数据存储到ptr指向的内存

size:读取元素的大小,unsigned int

count:读取元素的个数

stream:是指向FILE对象的指针,该FILE对象制定了一个输入流

返回值:

返回成功读取的对象个数,若出现错误或到达文件末尾,则可能小于count

若size或count为零,则fread返回零且不进行其他动作

fread不区分文件尾和错误,因此调用者必须用feof和ferror才能判断发生了什么

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#define N 10
int main()
{
	int arr[10] = { 0 };
	FILE*fp = fopen("Bin_File.txt", "rb");
	if (fp == NULL)
	{
		printf("打开失败!\n");
		exit(1);
	}
	fread(arr, sizeof(int), N, fp);
	fclose(fp);
	fp = NULL;
	system("pause");
	return 0;
}

 二进制文件存储的结构体类型数据读取

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>

struct Student
{
	char id[20];
	char name[20];
	char sex[8];
	int age;
};

int main()
{
	struct Student tmp = { 0 };
	FILE *fp = fopen("Bin_student.txt", "rb");
	if (fp == NULL)
	{
		printf("打开失败!\n");
		exit(1);
	}
	fread(&tmp, sizeof(struct Student), 1, fp);
	fclose(fp);
	fp = NULL;
	system("pause");
	return 0;
}

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值