栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

标准IO及其各函数用法

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

标准IO及其各函数用法

目录

综述标准IO与文件IO

1、fopen 函数(打开一个文件)

2、fclose函数(关闭流)

3、读写函数

3.1按字符读写

3.1.1 fgetc函数(从指定流中读取一个字符)

3.1.2 fputc函数(向流中输出一个字符)

3.1.3案例操作

3.2按行读写

3.2.1 fgets函数(按行读文件)

3.2.2 fputs函数(向文件中输出一串字符串)

3.2.3 小结

3.3按块读写

3.3.1 fread函数(按块读取内容)

3.3.2 fwrite函数(按块向流中写入数据)

3.3.3总结

4、perror函数

5、fseek、ftell、rewind函数


综述标准IO与文件IO

标准IO:

使用时在用户空间创建缓冲区,在合适的时机在通过系统调用访问实际的文件,从而减少了使用系统调用的次数。

缓存方式分三种:

行缓冲:n

全缓冲:缓存区填满内容才会溢出

不缓存:stderr

流:

当使用标准IO打开一个文件时,就会创建一个FILE结构体描述该文件,我们把这个FILE结构体形象的称为流,标准IO函数都是基于流进行各种操作。

文件指针:

指向一个打开文件的指针(硬盘中的文件被拷贝到内存中之后,会以FILE结构体的形态存在,要操作该文件必须使用文件指针)

FILE:

C语言file类,在stdio.h 头文件中,FILE类是一个结构体:定义如下:

struct _iobuf {
        char *_ptr;
        int   _cnt;
        char *_base;
        int   _flag;
        int   _file;
        int   _charbuf;
        int   _bufsiz;
        char *_tmpfname;
        };
typedef struct _iobuf FILE;

通过typedef定义了 文件类型 的别名: “FILE”,这样以后需要读写文件的时候直接就可以用FILE去定义。

文件IO:

1、不带缓存

2、通过文件描述符来访问文件

文件IO与标准IO的区别:

  1. 文件IO又被称为低级磁盘IO,遵循POSIX相关标准,任何兼容POSIX标准的操作系统上都支持文件IO。标准IO被称为高级磁盘IO,遵循ANSI C标准,只要开发环境中有标准C库,就可以使用标准IO。
  2. 文件IO读写文件时,每次操作都会执行相关的系统调用,这样可以直接读取实际文件,但是频繁的系统调用会增加系统的开销。标准IO可以看做是在文件IO的基础上封装了缓冲机制,从而减少了系统调用的次数。
  3. 文件IO中用文件描述符表示一个打开的文件,可以访问不同类型的文件。而标准IO使用流表示一个打开的文件,只能访问普通文件。

再来回顾一下各个文件类型

普通件 -

管道文件 p

链接文件 l

目录文件 d

套接字文件 s

块设备文件 b

字符设备文件 c

1、fopen 函数(打开一个文件)

FILE *fopen(const char *path, const char *mode)

FILE *fopen(要打开的文件路径及文件名, 以何方式打开 )

打开方式:r(只读)、w(只写)、a(追加写入)、r+(读写)、w+(读写)

返回值:成功,返回已经打开的文件流指针,失败返回NULL

2、fclose函数(关闭流)

int fclose(FILE *fp)

int fclose(已经打开的文件流指针)

返回值:

成功,返回0

失败,返回-1(EOF)(end of file,文件尾部的意思)

注意:EOF只能判断是否到文本文件的末尾,不能判断是否到二进制文件的末尾

判断是否关闭的代码

if (fclose(fp) != 0)

{

 printf("Error in closing file %sn", str1);

}

 ../2.txt表示上一级目录下的2.txt文件,此处按照实际情况来写就行。

errno.h,该头文件定义了通过错误码来回报错误资讯的宏。errno 宏定义为一个 int 型态的左值, 包含任何函式使用errno功能所产生的上一个错误码。

所以这里用的是%d这个格式控制符。

3、读写函数

当程序运行起来时,有三个文件默认已经打开,标准输入、标准输出、标准出错,对应的流指针分别为:stdin、stdout、stderr,这几个都是从键盘输入,终端输出,此次我们重点介绍的是从文件中读取,以及写入文件中。

3.1按字符读写

getchar( )、putchar( ) 只能从键盘输入

fgetc( )、fputc( ) 从哪里输入都可以:键盘、文件都可输入

3.1.1 fgetc函数(从指定流中读取一个字符)

int fgetc(FILE *stream)

int fgetc(指定的流),参数是读取字符的流来源

这个流可以写stdin,就是从键盘流输入,如果要用其他的流,从文件中读取和写入,需自己定义

返回值:成功返回输出的字符的ASCII值,失败返回-1

这个函数的返回值,是返回所读取的一个字节。如果读到文件末尾或者读取出错时返回EOF 

3.1.2 fputc函数(向流中输出一个字符)

int fputc(int c, FILE *stream);

int fputc(要输出的字符变量名, 要输出到哪的流?);

返回值:成功返回输出的字符的ASCII值,失败返回-1

3.1.3案例操作

用字符的读写模拟完成CP命令,如下:

3.2按行读写

3.2.1 fgets函数(按行读文件)

char *fgets(char *s, int size, FILE *stream)

char *fgets(读到内容放哪个地址, 能放的空间大小, 要操作的流(读它内容))

参数:

     s: 字符型指针,指向存储读入数据的缓冲区的地址

     size: 从流中读入n-1个字符

     stream : 指向读取的流

返回值:

成功,返回读到缓冲区字符串的首地址,

失败,返回NULL,遇到文件结尾也是返回NULL

注意:1、最多读size-1个字节

因为它遇到换行符,会将换行符也读入

3.2.2 fputs函数(向文件中输出一串字符串)

int fputs(const char *s, FILE *stream)

int fputs(内存空间的首地址, 要操作的流)

返回值:

成功,返回非负整数

失败,返回-1

3.2.3 小结

总结:fgets和gets有什么区别

fgets比gets安全

fgets会读取换行符,而gets不会

puts和fputs的区别

puts会自动换行,而fputs不会

3.3按块读写

3.3.1 fread函数(按块读取内容)

size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream)

size_t fread(接收保存数据的地址, 要读出内容的单字节数, 要进行读出size字节的数据项的个数, 要操作的流(目标文件指针))

fread函数每次从stream中最多读取nmemb个单元,每个单元大小为size个字节,将读取的数据放到ptr,文件流的指针后移size*nmemb字节。

由于每次移动的是size*nmemb,可以想象成二维变动(有两个变量值),所以我们叫它块读取

​ 

fread函数,每一次若读取成功,返回的是nmemb数值(这个值是我们自己设置的),如果返回值比nmemb要小,则可能是出错或者读取结束。

他还说到,fread函数无法区分是出错或者读取结束,需要借助feof函数或者ferror函数去进一步判断。

经验证,fread函数的返回值成功都是返回设定的nmemb值大小,只在最后一次,剩余的量不足以够nmemb,所以会返回一个比nmemb要小的值

 ​

feof函数用于检测是否到达文件末尾,如果到末尾,则返回是一个非零数。

3.3.2 fwrite函数(按块向流中写入数据)

size_t fwrite(const void *ptr, size_t size, size_t nmemb,FILE *stream)

size_t fwrite(内存空间首地址, 要写入内容的单字节数, 要进行写入size字节的数据项的个数,要操作的流)

size是sizeof(char),如果是char类型的,后一个参数是总的个数

返回值:

成功,返回写入的块数

失败,返回-1

3.3.3总结

此处用字符读写、按行读写、按块读写,模拟了虚拟机的CP命令,读者可以进行对比学习

#include
#include
int main(int argc,char *argv[])
{
	//入参检测
	if(argc < 3)
	{
		printf("try again");
		return -1;
	}
	//打开文件
	FILE *fr=fopen(argv[1],"r");
	FILE *fw=fopen(argv[2],"w");
	if((NULL == fr) || (NULL == fw))
	{
		printf("open error:%dn",errno);
		return -1;
	}

	//文件操作(模拟CP,通过块读写)
	char buf[50]="0";
	int test1,test2;
	while(1)
	{
		test1=fread(buf,1,15,fr);
		test2=feof(fr);
		//printf("fread的返回值:%dn",test1);
		//printf("feof的返回值:%dn",test2);
		if(test1 < 0)
		{
			perror("fread error");
			return -1;
		}
	    else if(test2 != 0)
		{
			break;
		}
		fwrite(buf,1,15,fw);
	}
	//关闭文件
	fclose(fr);
	fclose(fw);
	return 0;
}

4、perror函数

函数定义:

void perror(const char *s);

使用:

perror ("open_port");

包含头文件(不可以掉了这个头文件):

#include //包含perror的头文件

功能:perror ( )用 来 将 上 一 个 函 数 发 生 错 误 的 原 因 输 出 到 标 准 设备 (stderr) 。参数 s 所指的字符串会先打印出,后面再加上错误原因字符串。

5、fseek、ftell、rewind函数

首先,我们需要知道一点,文件在被操作时,文件指针会在文件内部自己移动

这三个函数都包含于stdio.h头文件中

函数的形式分别为:

int fseek(FILE *stream ,long offset ,int whence);

long ftell(FILE *stream);

Void rewind(FILE *stream);

函数

功能

返回值

fseek

重定位流上的文件指针

成功返回0

失败返回-1

ftell

获取当前文件指针位置

成功返回文件指针位置

失败返回-1

rewind

将文件内部指针重新指向文件的开头

无返回值

fseek的 whence参数设置,可以写英文,也可以写0,1,2,分别依次对应

起始点

代表的文件位置

对应数字

SEEK_SET

文件开头

0

SEEK_CUR

文件当前位置

1

SEEK_END

文件末尾

2

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/887665.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号