《UNIX环境高级编程》笔记 第五章——标准IO

1. 简介

标准IO相对于第三章文件IO来说,标准IO是库函数调用,而文件IO是系统调用。标准IO实现了读写数据的缓存机制,因此能够一定程度提高读写效率。标准IO提供了多个方便用户在不同应用场合的IO接口,这些IO接口有不同的缓冲类型,包含全缓冲、行缓冲和不带缓冲。标准IO围绕一个流的数据结构进行操作,标准IO库打开或创建文件时,都有一个流对象与之关联。标准输入流、标准输出流和标准错误流分别对应的流对象是stdin(STDIN_FILENO)、stdout(STDOUT_FILENO)和stderr(STDERR_FILENO)。

2. 函数原型

int fwide(FILE *fp, int mode)返回值:返回正值,则流是宽字节定向的;返回负值,则流是字节定向的;返回0,则流是未定向的

void setbuf(FILE *restrict fp, char *restrict buf)

int setvbuf(FILE *restrict fp, char *restrict buf, int mode size_t size)

更改缓冲类型

setvbuf返回值:若成功,返回0;若出错,返回-1

int fflush(FILE *fp)

强制冲洗一个流

返回值:若成功,返回0;若出错,返回-1

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

FILE *fdopen(int fd, const char *mode)

FILE *freopen(const char *pathname, const char *mode, FILE *stream)

打开一个流

3个函数返回值:若成功,返回文件指针;若出错,返回NULL

int fclose(FILE *fp)

关闭一个流

返回值:若成功,返回0;若出错,返回EOF

int getc(FILE *fp)

int  fgetc(FILE *fp)

int getchar(void)

getc可以被实现为一个宏,fgetc必须是一个函数

3个函数返回值:若成功,返回下一个字符;若出错或到达文件末尾,返回EOF

int ferror(FILE *fp)

int feof(FILE *fp)

2个函数返回值:若条件为真,返回非0;若条件为假,返回0
void clearerr(FILE *fp)清除错误和文件结束标志
int ungetc(int c, FILE *fp)

将字符压回流中(先进后出)

返回值:若成功,返回c;若出错,返回EOF

int fputc(int c, FILE *stream)

int putc(int c, FILE *stream)

int putchar(int c)
 

putc可以被实现为一个宏,fputc必须是一个函数

3个函数返回值:若成功,返回c;若出错,返回EOF

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

 char *gets(char *buf)

2个函数返回值:若成功,返回buf;若出错或到达文件末尾,返回NULL

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

int puts(const char *s)
 

2个函数返回值:若成功,返回非负值;若出错,返回EOF

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

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

二进制IO

2个函数返回值:读或写的对象数

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

long ftell(FILE *stream)

void rewind(FILE *stream)

ftell返回值:若成功,返回当前文件位置指示,若出错,返回-1

fseek返回值:若成功,返回0,若出错,返回-1

rewind将流设置到文件的起始位置

int fseeko(FILE *stream, off_t offset, int whence)

off_t ftello(FILE *stream)

与fseek和ftell作用相同

int fgetpos(FILE *stream, fpos_t *pos)

int fsetpos(FILE *stream, const fpos_t *pos)

2函数返回值:若成功,返回0;若出错,返回非0

int printf(const char *format, ...)

int fprintf(FILE *stream, const char *format, ...)
int dprintf(int fd, const char *format, ...)
int sprintf(char *str, const char *format, ...)
int snprintf(char *str, size_t size, const char *format, ...)

int vprintf(const char *format, va_list ap)
int vfprintf(FILE *stream, const char *format, va_list ap)
int vdprintf(int fd, const char *format, va_list ap)
int vsprintf(char *str, const char *format, va_list ap)
int vsnprintf(char *str, size_t size, const char *format, va_list ap)

 

格式化输出函数

int scanf(const char *format, ...);
int fscanf(FILE *stream, const char *format, ...);
int sscanf(const char *str, const char *format, ...);

int vscanf(const char *format, va_list ap);
int vsscanf(const char *str, const char *format, va_list ap);
int vfscanf(FILE *stream, const char *format, va_list ap);

 

格式化输入函数
int fileno(FILE *fp)返回值:返回与该流关联的文件描述符

char *tmpnam(char *s)

FILE *tmpfile()

char *mkdtemp(char *template)

int mkstemp(char *template)

创建临时文件或目录

FILE *fmemopen(void *buf, size_t size, const char *mode)

FILE *open_memstream(char **ptr, size_t *sizeloc);

FILE *open_wmemstream(wchar_t **ptr, size_t *sizeloc);
 

创建内存流

3. 实例

#include <stdio.h>
#include <wchar.h>
#include <unistd.h>
#include <string.h>

#define TEST_STR "Hello world!"

struct test_binary_rw {
	int n;
	short s1;
	short s2;
	char buf[8];
};


struct test_binary_rw binary_rw[] = {
	{1, 2, 3, "Hello"},
	{4, 5, 6, "world"},
	{7, 8, 9, "!"}
};

#define ARRAY_SIZE(arr) (sizeof(arr)/sizeof(arr[0]))

int main()
{
	int c;
	FILE *fp = fopen("test.txt", "w+");

	printf("fp: %d\n", fwide(fp, 0));	
	printf("fp: %d\n", fwide(fp, -1));

	for (int i = 0; i < strlen(TEST_STR); i++) {
		c = fputc(TEST_STR[i], fp);
		if (c != TEST_STR[i]) {
			printf("fputc error: %c\n", c);
			break;
		}
	}

	rewind(fp);
	while(1) {
		c = fgetc(fp);
		if (c == EOF) {
			break;
		}
		printf("%c", c);
	}
	printf("\n");

	FILE *fp2 = fopen("test2.txt", "w+");
	fwrite(binary_rw, sizeof(binary_rw[0]), ARRAY_SIZE(binary_rw), fp2);
	fwrite(TEST_STR, sizeof(char), strlen(TEST_STR), fp2);

	struct test_binary_rw tmp_rw[ARRAY_SIZE(binary_rw)+1] = {0};
	rewind(fp2);
	int r = fread(tmp_rw, sizeof(binary_rw[0]), ARRAY_SIZE(binary_rw)+1, fp2);
	printf("r = %d\n", r);
	for (int i = 0; i < ARRAY_SIZE(binary_rw); i++) {
		printf("n = %d, s1 = %d, s2 = %d, buf = %s\n", tmp_rw[i].n, tmp_rw[i].s1, tmp_rw[i].s2, tmp_rw[i].buf);
	}
	printf("TEST_STR: %s\n", (char *)&tmp_rw[ARRAY_SIZE(binary_rw)]);


	char wbuf[32] = {0};

	memset(wbuf, 'a', sizeof(wbuf)-1);
	printf("wbuf = %s\n", wbuf);
	FILE *mFp1 = fmemopen(wbuf, sizeof(wbuf), "w+");
	printf("wbuf = %s\n", wbuf);
	fprintf(mFp1, "123");
	printf("wbuf = %s\n", wbuf);
	fflush(mFp1);
	printf("wbuf = %s\n", wbuf);
	
	memset(wbuf, 'b', sizeof(wbuf)-1);
	fprintf(mFp1, "456");
	printf("wbuf = %s\n", wbuf);
	fseek(mFp1, 0, SEEK_SET);
	printf("wbuf = %s\n", wbuf);
	
	memset(wbuf, 'c', sizeof(wbuf)-1);
	fprintf(mFp1, "789");
	fflush(mFp1); // ??
	printf("wbuf = %s\n", wbuf);

	fprintf(mFp1, "ab");
	fflush(mFp1);
	printf("wbuf = %s\n", wbuf);

	fprintf(mFp1, "cd");
	fflush(mFp1);
	printf("wbuf = %s\n", wbuf);
	
}

4. 小结

1. 理解文件IO和标准IO的区别,标准IO的3种缓冲特性

2. 二进制IO函数的(fread和fwrite)的理解和应用以及各个字符和行相关的IO函数

3. 了解格式化输入和输出一系列函数

4. 了解临时文件的创建和应用

4. 了解内存流的使用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值