File input/Output in C
http://www.cs.bu.edu/teaching/c/file-io/intro/
/* example of file i/o */ int main(int argc, char **argv) { FILE *fp; int c, count = 0; *fp = fopen(argv[1], "r"); if(fp == NULL) { perror(argv[1]); exit(1); } while(1) { c = fgetc(fp); if( c == EOF ) break; count++; } fclose(fp); printf("%d bytes read\n", count); return 0; }
c/c++ feof()用法注意
有時候在使用檔案讀寫時,會遇到要判斷檔案結尾的需求,而C/C++語言在<stdio.h>中有提供一個feof()的函式幫助我們判斷,但是在使用時,請先了解它的使用時機。
下面的寫法模式會發生多讀取的case,而這個原因在於使用feof的時機不對。
FILE* pf; while(!feof(pf)){ //fread 讀取 //資料處理 }
feof是發生在fread使用"讀取過檔案"後,已讀到End-of-file位置時,回傳的指標才會是true(檔案結尾),所以上面的寫法在讀完最後一筆後,指標會停留在End-of-file位置前,需要再讀一次到在End-of-file位置後(判斷讀取資料失敗,因為已讀到eof),才會為true,而因為fread讀取失敗,buffer的資料不會改變,所以才會多讀一筆,如下圖:
改善的方式,如先使用fread讀取,再來判斷feof,當feof判斷為true時就跳離loop
while(1){ //fread讀取 if(feof(pf)) break; }
perror()用法
表头文件
#include<stdio.h>
定义函数
void perror(const char *s);
函数说明
perror ( )用 来 将 上 一 个 函 数 发 生 错 误 的 原 因 输 出 到 标 准 错误 (stderr) 。参数 s 所指的字符串会先打印出,后面再加上错误原因字符串。此错误原因依照全局变量 errno 的值来决定要输出的字符串。
范例:
#include <stdio.h> int main(void) { FILE *fp ; fp = fopen( "/root/noexitfile", "r+" ); if ( NULL == fp ) { perror("/root/noexitfile"); } return 0; }
结果:
root@localhost io]# gcc perror.c [root@localhost io]# ./a.out /root/noexitfile: No such file or directory
fopen() 和 fclose()
FILE *fopen(const char *path, const char *mode); flose(FILE *stream);
关于fclose(): It breaks the connection between the file pointer and the external name that was established by fopen, freeing the file pointer for another file. Since most operationg systerms have some limit on the number of files that a program may have open simutanously, It's a good idea to free file pointers when they are no longer needed, as we did in cat. There is also another reason for fclose on an output file - it flushes the buffer in which putc is collecting output. fclose is called automatically for wach open file when a program terminates normally. (quoted from K&R C)
不加的后果:造成文件描述符溢出;buffur is not flushed(比如向一个txt写入数据后,再读出这个txt的全部数据”,结果发现写入后没有fclose这个txt,只能读出原来的数据)
#include <stdio.h> int main() { int c; FILE* fp; // 建立空文件 fp = fopen("Info.txt", "w"); //需要用w来创建新文件,用r+会提示segmentation fault fputs("others\n",fp); if(NULL == fp) { printf("Cannot open file!\n"); return 0; } //fclose(fp); fp = fopen("Info.txt", "r"); if(NULL == fp) { printf("Cannot open file!\n"); return 0; } while(1) { c = fgetc(fp); if(c==EOF) break; else printf("%c",c); } fclose(fp); return 0; } Output: 如果没有fclose,则无输出 如果有fclose,则输出others
fseek and ftell
fseek函数是用来设定文件的当前读写位置. 函数原型:
int fseek(FILE *fp,long offset,int origin);
函数功能:把fp的文件读写位置指针移到指定的位置.
ftell函数是用来获取文件的当前读写位置. 函数原型:
long ftell(FILE *fp)
函数功能:得到流式文件的当前读写位置,其返回值是当前读写位置偏离文件头部的字节数.
fseek函数与ftell函数综合应用:
分析:可以用fseek函数把位置指针移到文件尾,再用ftell函数获得这时位置指针距文件头的字节数,这个字节数就是文件的长度.
#include <stdio.h> int main() { FILE *fp; char filename[80]; long length; printf("Input the file name:"); gets(filename); fp=fopen(filename,"rb"); if(fp==NULL) printf("file not found!/n"); else { fseek(fp,0,SEEK_END); length=ftell(fp); printf("the file length %ld bytes/n",length); fclose(fp); } return 0; }