流的打开和关闭
-
头文件
#include <stdio.h>
-
函数原型
FILE *open(const char *path, const char *mode); /*第一个参数是文件名路径,第二个参数是打开模式*/
int fclose(*fp); /*参数为打开的流*/
-
返回值
fopen打开成功则此函数返回一个FILE指针(流指针),所以申明一个FILE指针后不用初始化,而是用fopen来返回一个指针并与一个特定的文件相连,如果成败,返回NULL。
fclose成功返回0,失败返回EOF,与fopen函数配套使用。
示例
#include <stdio.h>
#include <errno.h>
int main(int argc,const char *argv[])
{
FILE *fp;
/*参数检测*/
if (argc < 2) {
printf("Usage:%s <src_file>\n",argv[0]);
return -1;
}
/*以只读方式打开*/
if ((fp = fopen(argv[1],"r")) == NULL) {
perror("fopen");
return -1;
}
fclose(fp);
return 0;
}
读写流
-
按字符读写
头文件
include <stdio.h>
函数原型
int fgetc(FILE *stream); /*stream 是指向 FILE 结构体的指针,该 FILE 结构体标识了要在上面执行操作的流。*/
int fputc(int c, FILE *stream); /*将参数一中内容写入 stream 指向的流里*/
返回值
fgetc 从 stream 中读取下一个字符,返回值为读取到的字符(强转为int型),读取到文件末尾或出错时返回 EOF;
fputc 成功返回写入的字符,出错则返回 EOF ,并设置错误标志符;
getchar()等同于fgetc(stdin);
putchar(c)等同于fputc(c,stdout);
示例 (实现拷贝功能,并统计字符数)
#include <stdio.h>
#include <errno.h>
int main(int argc,const char *argv[])
{
FILE *fps,*fpd;
int ch; /*缓存读取到字符*/
int count = 0;
if (argc < 3) {
printf("Usage:%s <src_file> <dest_file>\n",argv[0]);
return -1;
}
/*打开源文件*/
if ((fps = fopen(argv[1],"r")) == NULL) {
perror("fopen");
return -1;
}
/*打开目标文件*/
if ((fpd = fopen(argv[2],"w+")) == NULL) {
perror("fopen");
return -1;
}
/*1直到读取到文件末尾结束*/
while ((ch = fgetc(fps)) != EOF) {
fputc(ch,fpd);
count++;
}
printf("copy success, the filesize is %d\n",count);
fclose(fps);
fclose(fpd);
return 0;
}
-
按行读写
头文件
#include <stid.h>
函数原型
char *fgets(char *s, int size, FILE *stream); /*将stream指向的流的数据读取到字符指针s指向的缓存区中,读入size - 1个字符 */
int fputs(const char *s, FILE *stream); /*将缓存中的数据写入stream指向的流中*/
返回值
fgets 读取成功返回缓存区的地址s(字符型),到文件末尾或出错时返回 NULL;
fputs 成功时返回写入字符个数 ,出错时返回 EOF;
- 示例 (实现拷贝功能,并统计行数)
#include <stdio.h>
#include <errno.h>
#include <string.h>
#define N 64
int main(int argc,const char *argv[])
{
FILE *fps,*fpd;
char buf[N];
int line = 0;
/*参数检测*/
if (argc < 3) {
printf("Usage:%s <src_file> <dest_file>\n",argv[0]);
return -1;
}
/*打开源文件*/
if ((fps = fopen(argv[1],"r")) == NULL) {
perror("fopen");
return -1;
}
/*打开目标文件*/
if ((fpd = fopen(argv[2],"w+")) == NULL) {
perror("fopen");
return -1;
}
while (fgets(buf,N,fps) != NULL) {
if (buf[strlen(buf) - 1] == '\n')
line++;
fputs(buf,fpd);
}
printf("line = %d\n",line);
fclose(fps);
fclose(fpd);
return 0;
}
-
按对象读写
头文件
#include <stdio.h>
函数原型
size_t fread(void *ptr, size_t szie, size_t nmemb, FILE *stream);
ptr 为缓存地址
size 为每个数据的长度
nmemb 为读取的数据个数
stream 源文件流
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);/*将参数一的内容写入参数四目标流里*/
返回值
成功返回读写的对象个数;出错时返回 EOF
既可以读写文本文件,也可以读写数据文件
效率高
示例
#include <stdio.h>
#include <errno.h>
#define N 64
int main(int argc,const char *argv[])
{
FILE *fps,*fpd;
int n;
char buf[N];
if (argc < 3) {
printf("Usage:%s <src_file> <dst_file>\n",argv[0]);
return -1;
}
/*打开源文件和目标文件*/
if ((fps = fopen(argv[1],"r")) == NULL) {
perror("fopen");
return -1;
}
if ((fpd = fopen(argv[2],"w+")) == NULL) {
perror("fopen");
return -1;
}
/*读写流*/
while ((n = fread(buf,1,N,fps)) > 0) { /*当n接收到的字符数小于0时,表示已经读取到文件的末尾*/
fwrite(buf,1,n,fpd);
}
fclose(fps);
fclose(fpd);
return 0;
}
-
格式化输出
头文件
#include <stdio.h>
函数原型
int printf(const char *fmt, ...);
int fprintf(FILE *stream, const char *fmt, ...); /*以指定的格式将一个字符串输出到一个流中*/
int sprintf(char *s,const *fmt, ...); /*以指定的格式将一个字符串输出到一个缓冲区中*/
返回值
成功时返回输出字符的个数,出错时返回 EOF;
-
定位流
头文件
#include <stdio.h>
函数原型
long ftell(FILE *stream);
int fseek(FILE *stream, long offset, int whence); /*whence 为基准点,offset为偏移量,值可正可负*/
void rewind(FILE *stream);
返回值
ftell() 成功时返回流的当前位置,出错时返回 EOF;
fseek() 定位一个流,偏移量加上起始地址值不得小于0,但是可以超出当前位置的长度。成功时返回0,出错时返回 EOF;
whence 参数:SEEK_SET(文件起始位置) / SEEK_CUR(文件当前位置) / SEEK_END(文件末尾);
rewind() 将文件定位到起始位置;
读写流的时候,当前位置自动后移;
-
判断流是否出错和结束
头文件
#include <stdio.h>
函数原型
int ferror(FILE *stream);
int feof(FILE *stream);
返回值
ferror() 用来检测流是否出错,返回 1 表示流出错;否则返回 0;
feof() 用来判断流是否读取到末尾,返回 1表示已到末尾,否则返回 0;
这两个函数是用来检测,值为逻辑真假,而不是用来判断是否成功