巩固C语言(十一)----文件的数据处理

一 单线程文件处理,边读取边处理

#define _CRT_SECURE_NO_WARNINGS

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

void main()
{
	clock_t start, finish;
	double duration;
	FILE *fp = fopen("dangdangwang.txt", "rb");
	if (!fp)
	{
		printf("读文件打开失败!\n");
		system("pause");
		exit(-1);
	}
	FILE *wp = fopen("result.txt", "wb");
	if (!wp)
	{
		printf("写文件打开失败!\n");
		system("pause");
		exit(-1);
	}

	//fseek接受三个参数,一切正常返回0,否则返回-1;
	//第一个参数为指向被搜索文件的指针;
	//第二个参数为偏移量,long类型,可为正、负和零;
	//第三个参数为模式,用来标识起始点,SEEK_SET 文件开始,SEEK_CUR 当前位置, SEEK_END 文件结尾
	int s = fseek(fp, 0L, SEEK_END);

	if (s == 0)
	{
		//以一个long类型值返回一个文件的当前位置,返回的是字节数目
		long sz = ftell(fp);
		printf("当前文件大小为%ldB字节, %lfKB, %lfMB, %lfGB\n", sz, sz / 1024.0, sz / (1024.0*1024.0), sz / (1024.0*1024.0*1024.0));
		fprintf(wp, "当前文件大小为%ldB, %lfKB, %lfMB, %lf%GB\n", sz, sz / 1024.0, sz / (1024.0*1024.0), sz / (1024.0*1024.0*1024.0));
	}

	//开始查找
	char ch[20] = {0};
	printf("请输入要查找的内容,输入字符\'*\'代表结束:");
	scanf("%s", ch);
	while (*ch != '*')
	{
		start = clock();
		rewind(fp);			//回到文件开始处
		char buf[4096] = { 0 };
		int num = 0;
		while (fgets(buf, 4096, fp)!=NULL && buf[0]!='\n')
		{
			if (strstr(buf, ch))
			{
				num++;
				printf("%s\n", buf);
				fprintf(wp, "%s\n", buf);
			}
		}
		finish = clock();
		duration = (double)(finish - start)/CLOCKS_PER_SEC;
		printf("\n===============共%d条结果,耗时:%2.2f秒===============\n\n", num, duration);
		fprintf(wp, "\n===============共%d条结果,耗时:%2.2f秒===============\n\n", num, duration);
		printf("请输入要查找的内容,输入字符\'*\'代表结束:");
		scanf("%s", ch);
	}
	fclose(fp);
	fclose(wp);

	system("pause");
}

运行结果:
lz687197@dangdang.com,赵四清,东大街20号生物安全中心实验室,111,1,01066948312,13321126010,481.00

ceangel78@163.com,赵四方,青岛中路72号第二热电厂,137,1113,15863103610,13869047158,33.40


==============共49条结果,耗时:10.01秒===============
goto8381@126.com,刘能祥,御道街53号南京震天宇公司 (送货前先电话联系),132,1601,,13851788720,51.00

goto8381@126.com,刘能祥,御道街53号南京震天宇公司 (送货前先电话联系),132,1601,,13851788720,30.40

xuchengzhu@126.com,刘能慧,东方路989号中达广场25楼浦发银行TM部,131,3,50327750,13402027248,17.50


===============共79条结果,耗时:4.08秒===============


注意:该程序不需要将文本读入内存,在检索的时候一边读入文本一边进行检索,所以耗时较长,经测试,最短时长为3秒。

二 单线程文件处理,将文本内容读入内存中

#define _CRT_SECURE_NO_WARNINGS

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

char **p = NULL;		//存放指针数组的地址

//获取文件大小
long GetFileSize(char *path)
{
//	printf("开始处理文件大小......\n");
	FILE *fp = fopen(path, "r");
	if (!fp)
	{
		printf("文件读取失败!\n");
		return -1;
	}
	fseek(fp, 0, SEEK_END);
	long sz = ftell(fp);
//	printf("\t该文件大小为%lddB, %fKB, %fMB, %fGB\n", sz, sz / 1024.0, sz / (1024.0*1024.0), sz / (1024.0*1024.0*1024.0));
	fclose(fp);
	
	return sz;
}

//获取行数, 13180807行
long GetLineNum(char *path)
{
//	printf("开始处理行数......\n");
	FILE *fp = fopen(path, "r");
	if (!fp)
	{
		printf("文件读取失败!\n");
		return -1;
	}
	
	long n = 0;
	//It returns 0 if the current position is not end of file. ----From MSDN
	while (!feof(fp))
	{
		char tem[275] = { 0 };
		n++;
		fgets(tem, 275, fp);
	}
	fclose(fp);
//	printf("\t该文件共有%ld行。\n", n);

	return n;
}

//将文件内容加载到内存中
//将每一行的地址赋予指针,以便存储节约内存空间
void GetTextToMemory(char *path, long lineNO)
{
//	printf("将文本内容载入内存\n");
	p = (char **)malloc(lineNO * sizeof(char *));		//分配指针数组
	FILE *fp = fopen(path, "r");
	if (!fp)
	{
		printf("初始化失败!\n");
		return;
	}
	for (long i = 0; i < lineNO; i++)
	{
		char tem[512] = { 0 };								//读取字符串的缓冲区
		fgets(tem, 512, fp);								//从文件中逐行读取字符串
		int len = strlen(tem) + 1;							//实际读出的字符串+1
		char *px = (char *)malloc(len * sizeof(char));		//为每一行读取的数据开辟空间
		strcpy(px, tem);									//拷贝字符串
		px[len - 1] = '\0';									//设置最后一个字符为'\0'
		p[i] = px;											//存储字符串的首地址到指针数组
	}
//	printf("载入内存成功!\n");


}

void FindStr(char *str, long n)
{
	long line = 0;
	for (long i = 0; i < n; i++)
	{
		if (strstr(p[i], str) != NULL)
		{
			printf("%s\n", p[i]);
			line++;
		}
	}
	printf("======================共有%d行===========================\n", line);
}
void main()
{
	time_t start, finish;
	char *path = "F:\\下载\\学习\\精品软件\\dangdangwang.txt";
	printf("开始文件处理......\n");

	long n = GetLineNum(path);
	GetFileSize(path);
	GetTextToMemory(path, n);

	printf("文件处理结束!\n");

	char str[40] = { 0 };
	printf("请输入您要查询的内容(输入字符\'*\'代表结束!):");
	scanf("%s", str);
	while (str[0] != '*')
	{
		start = clock();
		FindStr(str, n);
		finish = clock();
		double dur = (double)(finish - start) / CLOCKS_PER_SEC;
		printf("======================耗时%.2f秒===========================\n", dur);
		printf("请输入您要查询的内容(输入字符\'*\'代表结束!):");
		scanf("%s", str);
	}

	system("pause");
}

运行结果:
iceangel78@163.com,赵四方,青岛中路72号第二热电厂,137,1113,15863103610,13869047158,33.40

======================共有49行===========================
======================耗时0.52秒===========================
goto8381@126.com,刘能祥,御道街53号南京震天宇公司 (送货前先电话联系),132,1601,,13851788720,51.00

goto8381@126.com,刘能祥,御道街53号南京震天宇公司 (送货前先电话联系),132,1601,,13851788720,30.40

xuchengzhu@126.com,刘能慧,东方路989号中达广场25楼浦发银行TM部,131,3,50327750,13402027248,17.50

======================共有79行===========================
======================耗时0.45秒===========================
请输入您要查询的内容(输入字符'*'代表结束!):*

该程序初始化阶段用时较长,而检索时间耗时较短。与上一个程序效率上高了很多。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值