C语言进阶-第35讲:标准文件读写方法(以字符/字符串复制文件引发的思考)
2017-11-30 21:49
435 查看
任务和代码(一):
任务和代码(二):
Q&A:
Q1:代码(二)中,又见feof()函数,运行后,打开b.txt,少一行,为什么?怎么改?
A1:执行最后一条fgets()后,最后一行字符串被读到,但此时文件指针已指向文件末尾,退出循环
改进1,在循环体后加上输出语句fputs(string, fp2);
改进2,在a.txt文件末尾多一段空白行。
Q2:feof()与EOF结束符有什么区别?在代码(一)中能否用feof()实现?代码(二)呢?
A2:EOF,文件结束符,值为-1;feof()的函数原型 int feof(FILE *stream);文件结束返回1,否则为0
以字符为单位复制文件时,fgetc()的返回值是int(char也可以理解为int),而EOF的值为-1,就可以判断文件指针指向的字符是否到了文件结束位置;
将代码(一)中的循环体修改如下:
由此看出,feof()用于判断文件指针是否指向了文件结束,其使用要比用EOF结束符用于判断的范围广
Q3:能用fgetc()、fgets()读取文件指针,能不能换成fscanf()?若能,如何?
A3:首先介绍 fgetc() 、fgets() 、fscanf()是如何读取文本文件的
scanf()/getchar() //只有遇到回车会将回车读入缓存区并结束,当读入空格、\t 时不会结束
scanf("%s",str); //遇空格、\t、回车结束
gets(str); //遇空格、\t不结束, 遇回车结束
fgetc() //会读入每一个字符直到文件指针指向文件结束符
fgets() //只遇到换行符文件指针才移到下一字符串(按行读取)
fscanf() //遇到空格、\t和换行时文件指针指向下一字符串(读入格式化数据)
用fscanf()修改代码(二)试试:
Q4:fcanf()与fgers()/fread()读到文件末尾的区别?
A4:fscanf完最后一行,fp未指向文件末尾,继续读取循环语句,再次fscanf后,跳出循环
fgets/fread完最后一行,fp1已指向文件末尾,下一步跳出循环,毫不含糊!
因此在A1中,还可以这样做:
Q5:还有没有其他方式可以替换feof()函数的使用?
A5:以字符串为单位复制文件为例,将代码(二)的循环体做以下修改:
一:以fgets()读取文件
二:以fscanf()读取文件
PS:
任务和代码(三):
运行结果:
/*以字符为单位复制文件*/ #include <stdio.h> #include <stdlib.h> int main() { FILE *fp1,*fp2; char ch; if((fp1=fopen("a.txt","r"))==NULL) /*打开用于复制的源文件*/ { printf("Cannot open source file.\n"); exit(1); } if((fp2=fopen("b.txt","w+"))==NULL) /*打开用于写入的目标文件*/ { printf("Cannot open traget file.\n"); exit(1); } while((ch=fgetc(fp1))!=EOF) /*从源文件中逐个地读出字符*/ fputc(ch,fp2); /*将读出的字符逐个写入到文件*/ fclose(fp1); fclose(fp2); return 0; }
任务和代码(二):
/*以字符串为单位复制文件*/ #include <stdio.h> #include <stdlib.h> int main() { FILE *fp1,*fp2; char string[80]; /*定义字符数组,用于读入字符串*/ if((fp1=fopen("a.txt","r"))==NULL) /*打开用于复制的源文件*/ { printf("Cannot open source file.\n"); exit(1); } if((fp2=fopen("b.txt","w+"))==NULL) /*打开用于写入的目标文件*/ { printf("Cannot open traget file.\n"); exit(1); } fgets(string, 80, fp1); /*从源文件中读入字符串*/ while(!feof(fp1)) /*若未结束*/ { fputs(string, fp2); /*将读入的字符串写入目标文件*/ fgets(string, 80, fp1); /*继续从源文件中读入字符串*/ } fclose(fp1); fclose(fp2); return 0; }a.txt
Q&A:
Q1:代码(二)中,又见feof()函数,运行后,打开b.txt,少一行,为什么?怎么改?
A1:执行最后一条fgets()后,最后一行字符串被读到,但此时文件指针已指向文件末尾,退出循环
改进1,在循环体后加上输出语句fputs(string, fp2);
改进2,在a.txt文件末尾多一段空白行。
Q2:feof()与EOF结束符有什么区别?在代码(一)中能否用feof()实现?代码(二)呢?
A2:EOF,文件结束符,值为-1;feof()的函数原型 int feof(FILE *stream);文件结束返回1,否则为0
以字符为单位复制文件时,fgetc()的返回值是int(char也可以理解为int),而EOF的值为-1,就可以判断文件指针指向的字符是否到了文件结束位置;
将代码(一)中的循环体修改如下:
ch=fgetc(fp1); while(!feof(fp1)){ fputc(ch,fp2); ch=fgetc(fp1); }而以字符串为单位复制文件时,fgets()的返回值是地址,与EOF的类型不匹配。
由此看出,feof()用于判断文件指针是否指向了文件结束,其使用要比用EOF结束符用于判断的范围广
Q3:能用fgetc()、fgets()读取文件指针,能不能换成fscanf()?若能,如何?
A3:首先介绍 fgetc() 、fgets() 、fscanf()是如何读取文本文件的
scanf()/getchar() //只有遇到回车会将回车读入缓存区并结束,当读入空格、\t 时不会结束
scanf("%s",str); //遇空格、\t、回车结束
gets(str); //遇空格、\t不结束, 遇回车结束
fgetc() //会读入每一个字符直到文件指针指向文件结束符
fgets() //只遇到换行符文件指针才移到下一字符串(按行读取)
fscanf() //遇到空格、\t和换行时文件指针指向下一字符串(读入格式化数据)
用fscanf()修改代码(二)试试:
fscanf(fp1,"%s",string); while(!feof(fp1)) { fprintf(fp2,"%s",string); fscanf(fp1,"%s",string); }其运行结果就是b.txt中出现连续的一整串字符,了解fscanf() 的读取方式后就明白,被空格、\t和换行符间隔的字符或字符串都作为字符串进行读取
Q4:fcanf()与fgers()/fread()读到文件末尾的区别?
A4:fscanf完最后一行,fp未指向文件末尾,继续读取循环语句,再次fscanf后,跳出循环
fgets/fread完最后一行,fp1已指向文件末尾,下一步跳出循环,毫不含糊!
因此在A1中,还可以这样做:
while(!feof(fp1)) { fgets(string, 80, fp1); fputs(string, fp2); }注意,在使用while(!feof(fp))时,只有当扫描语句是fscanf时,才要将其放在循环体内其他语句之后。
Q5:还有没有其他方式可以替换feof()函数的使用?
A5:以字符串为单位复制文件为例,将代码(二)的循环体做以下修改:
一:以fgets()读取文件
while (fgets(string, 80, fp1) != NULL) { fputs(string, fp2); }
二:以fscanf()读取文件
while (fscanf(fp1, "%s", string) == 1) { fprintf(fp2, "%s", string); }
PS:
任务和代码(三):
/*使用非标准文件操作实现文件的复制功能*/ #include <stdio.h> #include <fcntl.h> //包含非标准文件操作的头文件 #include <stdlib.h> int main() { int handle1, handle2; //文件号,读写文件时和文件相联系(而非FILE *fp) char ch, filename1[20], filename2[20]; printf("enter source filename:"); gets(filename1); if((handle1=open(filename1, O_RDONLY))==-1) //int型文件号,打开失败返回1 exit(1); printf("enter destination filename:"); gets(filename2); if((handle2=open(filename2, O_WRONLY))==-1) exit(1); while(read(handle1, &ch, 1)>0) //从文件号为handle1的文件中读一个字节的数据给内存变量ch,无读入数据,返回-1 write(handle2, &ch, 1); //讲一个字节的字符变量i的值存入文件号为handle2的文件中 puts("Success"); close(handle1); close(handle2); return 0; }
运行结果:
相关文章推荐
- C语言及程序设计进阶例程-35 标准文件读写方法
- C语言小程序:除去字符串中间不需要的字符(从小引发大思考)
- IO(六、)复制文件方法一:一个字符一个的读写
- C语言代码分享之字符串匹配及文件读写结合
- C语言对文件的读写操作以及处理CSV文件的方法
- cpp如何快速安全地将文件读入字符串string或字符数组vector<string>的方法
- c++ 文件复制 往文件中输入字符、数字、字符串
- Unicode(UTF16)文件读写终极方案---用C++标准的字节流读取,转化为宽字符(wchar_t),再以字节流写入
- C语言:有一个字符串,包含n个字符。写一个函数,将此字符串中从第m个字符开始的全部字符复制成为另一个字符串
- 常用方法归档-获取<日期、字符串倒写、随机数、读写文件>
- 【C语言】 两种不同的方法在一个字符串中找指定的字符
- 含读写及替换字符的复制文件操作
- (六)两种方式将一个文件的内容复制到另一个文件(第二种方式效率更高,第一种一个字符一个字符的读写,第二种一个数组一个数组的读写)
- 小记:删除字符串空格的3种方法所引发的对C library 中库函数的思考
- 字符流方法实现复制文件
- c语言以字符形式实现文件的读写操作
- c语言文件读写操作 去掉文件每行的前六个字符
- C++ 文件读写 字符输出 字符串输出
- IO流__【概述】【字符文件的读写和复制】【字符流缓冲区】
- Unicode(UTF16)文件读写终极方案---用C++标准的字节流读取,转化为宽字符(wchar_t),再以字节流写入