c primer plus 专题13:文件

1 与文件进行通信

1 文件重定向

文件重定向的程序

/* write_file.c -- 数据写入到文件 */
#include <stdio.h>

int main(void)
{
	int i;
	char * pc;
	const char *ptc[3] = { "hello c", "hello java", "hello python" };

	for (i = 0; i < 3; i++)
	{
		pc = ptc[i];
		while (*pc != '\0')
		{
			putchar(*(pc++));
		}
		putchar('\n');
	}

	return 0;
}

文件重定向

文件内容

2 文件是什么?

C语言把文件看作一系列连续的字节,每个字节都能被单独读取,这与UNIX环境中的文件结构相对应。C提供两种文件模式:文本模式和二进制模式

3 标准文件

2 标准IO

#include <stdio.h>
#include <stdlib.h>		/* 提供 exit() 函数原型 */

int main(int argc, char *argv[])
{
	int ch;		// 读取文件时,存储每个字符的地方
	FILE *fp;	// 文件指针
	unsigned long int count = 0;	// 文件字符计数
	if (argc != 2)
	{
		printf("Usage %s filename\n", argv[0]);		// exe路径
		exit(EXIT_FAILURE);
	}
	if ((fp = fopen(argv[1], "r")) == NULL)
	{
		printf("Can't open %s\n", argv[1]);			// 待读取文件路径
		exit(EXIT_FAILURE);
	}
	while ((ch = getc(fp)) != EOF)
	{
		putc(ch, stdout);			// 在屏幕上显示
		count++;
	}
	fclose(fp);
	printf("File %s has %lu characters.\n", argv[1], count);
	
	return 0;
}

程序执行结果

程序分析

1 检查命令行参数

2 fopen() 函数

3 getc() 函数 putc() 函数  从文件中读取 / 写入字符

4 fclose() 函数

5 指向标准文件的指针

3 简单的压缩程序

/* main.c -- 把文件压缩成原来的 1/3 */
#include <stdio.h>
#include <stdlib.h>		/* 提供 exit() 函数原型 */
#include <string.h>		/* 提供 strncpy() 函数原型 */
#define LEN		40

int main(int argc, char *argv[])
{
	FILE *in, *out;		/* 声明两个指向 FILE 的指针 */
	int ch;
	char name[LEN];		/* 存储输出文件名 */
	int count = 0;

	/* 检查命令行参数 */
	if (argc < 2)
	{
		fprintf(stderr, "Usage %s filename\n", argv[0]);
		exit(EXIT_FAILURE);
	}
	/* 设置输入 */
	if ((in = fopen(argv[1], "r")) == NULL)
	{
		fprintf(stderr, "I couldn't open the file\" %s \"\n", argv[1]);
		exit(EXIT_FAILURE);
	}
	/* 设置输出 */
	strncpy(name, argv[1], LEN - 5);	/* 拷贝文件名 */
	name[LEN - 5] = '\0';				/* 字符串过长时,strcpy() 函数不拷贝 '\0' */
	strcat(name, ".red");				/* 在文件名后面添加 .red */
	if ((out = fopen(name, "w")) == NULL)
	{
		fprintf(stderr, "Can'create output file\n");
		exit(EXIT_FAILURE);
	}
	/* 压缩拷贝数据 */
	while ((ch = getc(in)) != EOF)
	{
		if (count++ % 3 == 0)
			putc(ch, out);				/* 向 out 文件中写入 1/3 的数据 */
	}
	/* 关闭文件 */
	if (fclose(in) != 0 && fclose(out) != 0)
		fprintf(stderr, "Error in closing files.\n");
	
	return 0;
}

test.txt 的文件内容如下:

So even Eddy came oven reddy.

程序执行结果如下

生成的文件 test.txt.red 

程序说明:

4 文件IO

1 fprintf() 函数  fscanf() 函数

测试程序如下:

#include <stdio.h>
#include <stdlib.h>		
#include <string.h>		
#define MAX		41

int main(void)
{
	FILE * fp;
	char words[MAX];

	if ((fp = fopen("wordy.txt", "a+")) == NULL)
	{
		fprintf(stderr, "Can't open \" wordy.txt \"\n");
		exit(EXIT_FAILURE);
	}
	puts("Enter words to add to the file; press the #");
	puts("key at the beginning of a line to terminate.");
	/* 从键盘获取输入字符串,并输出到 fp 文件流 */
	while ((fscanf(stdin, "%s", words)) == 1 && words[0] != '#')
		fprintf(fp, "%s\n", words);
	puts("File contents:");
	rewind(fp);					/* 返回到文件开始处 */
	while (fscanf(fp, "%s", words) == 1)
		puts(words);
	puts("Done!");
	if (fclose(fp) != 0)
		fprintf(stderr, "Error closing file\n");
	
	return 0;
}

程序执行结果(a+模式只允许在文件末尾添加内容,但可以读整个文件)

2 fgets() 函数和 fputs() 函数

5 随机访问 fseek() 函数 ftell() 函数

倒序打印文件的程序

#include <stdio.h>
#include <stdlib.h>		
#define CTRL_Z	'\032'		/* DOS文本文件中的文件结尾标记 */
#define SLEN	81
char *s_gets(char *st, int n);

int main(void)
{
	char file[SLEN];
	int ch;
	FILE * fp;
	long int count, last;

	puts("Enter the name of the file to be processed:");
	/* 直接使用 fgets() 函数,会保留\n,导致打开文件失败 */
	s_gets(file, SLEN);						
	if ((fp = fopen(file, "rb")) == NULL)	/* 只读二进制模式 */
	{
		printf("Reverse can't open %s\n", file);
		exit(EXIT_FAILURE);
	}
	fseek(fp, 0L, SEEK_END);			/* 定位至文件末尾,偏移0 */
	last = ftell(fp);					/* 获取当前位置相对于文件首的偏移字节数 */
	for (count = 1; count <= last; count++)
	{
		fseek(fp, -count, SEEK_END);	/* 回退一字节 */
		ch = getc(fp);
		/* 为了兼容 MS-DOS,\r\n换行,Ctrl+Z 结束 */
		if (ch != CTRL_Z && ch != '\r')	/* MS-DOS文件 */
			putchar(ch);
	}
	putchar('\n');
	fclose(fp);
	
	return 0;
}

/* 最多读取 n 字节的字符串,删除末尾的 \n,清空缓冲区 */
char *s_gets(char *st, int n)
{
	int i = 0;
	char *ret_val;

	ret_val = fgets(st, n, stdin);
	if (ret_val)
	{
		while (ret_val[i] != '\n' && ret_val[i] != '\0')
			i++;
		if (ret_val[i] == '\n')
			ret_val[i] = '\0';
		else
			while (getchar() != '\n')
				continue;
	}
	
	return ret_val;
}

程序执行结果

1 fseek() 函数原理

2 程序的兼容性

6 标准IO机理

7 其他标准IO函数

1 ungetc() 函数 放回字符到输入流

2 fflush() 函数  刷新缓冲区

3 二进制IO函数

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

文本文件

二进制文件

关于 sprintf() 函数和 fwrite() 函数的区别

4 fwrite() 函数

5 fread() 函数

6 用二进制IO进行随机访问

#include <stdio.h>
#include <stdlib.h>		
#define ARSIZE	1000

int main(void)
{
	double numbers[ARSIZE];
	double value;
	const char * file = "numbers.dat";
	int i;
	long pos;
	FILE * fp;

	/* 创建一组double类型的值 */
	for (i = 0; i < ARSIZE; i++)
		numbers[i] = i + 0.01;
	/* 尝试打开文件 */
	if ((fp = fopen(file, "wb")) == NULL)	/* 二进制写入打开文件 */
	{
		fprintf(stderr, "Could not open %s for output.\n", file);
		exit(EXIT_FAILURE);
	}
	/* 以二进制格式写入文件 */
	fwrite(numbers, sizeof(double), ARSIZE, fp);
	fclose(fp);
	if ((fp = fopen(file, "rb")) == NULL)	/* 二进制读取打开文件 */
	{
		fprintf(stderr, "Could not open %s for random access.\n", file);
		exit(EXIT_FAILURE);
	}
	/* 从文件中读取选定的内容 */
	printf("Enter an index in the range 0-%d.\n", ARSIZE - 1);
	while (scanf("%d", &i) == 1 && i >= 0 && i < ARSIZE)
	{
		pos = i * sizeof(double);
		fseek(fp, pos, SEEK_SET);		/* 定位到文件偏移处 */
		fread(&value, sizeof(double), 1, fp);
		printf("The value there is %f.\n", value);
		printf("Next index (out of range to quit) :\n");
	}
	fclose(fp);
	puts("Done!");
	
	return 0;
}

程序执行结果

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值