-
标准IO函数
查看错误码 vi -t EEXIST
打开文件:fopen freopen
1)fopen 打开文件
FILE *fopen(const char *path, const char *mode)
功能:打开文件
参数:
path:打开的文件
mode:打开的方式
r:只读,当文件不存在时报错,文件流定位到文件开头
r+:可读可写,当文件不存在时报错,文件流定位到文件开头
w:只写,文件不存在创建,存在清空
w+:可读可写,文件不存在创建,存在清空
a:追加(在末尾写),文件不存在创建,存在追加,文件流定位到文件末尾
a+:读和追加,文件不存在创建,存在追加,读文件流定位到文件开头,写文件流定位到文件末尾
注:当a的方式打开文件时,写只能在末尾进行追加,定位操作是无法改变写的位置,但是可以改变读的位置
返回值:成功:文件流
失败:NULL,并且会设置错误码
a+:初始读指针在文件开始位置,写指针在文件结束位置,如果只调用读指针,那么读指针从刚开始位置后移,一旦调用写指针,读写指针合二为一,读指针去到写指针的位置
2)freopen
关闭文件:fclose
int fclose(FILE* stream);
功能:关闭文件
参数:stream:文件流
读写操作:fgetc fputc fgets fputs fread fwrite
1)每次读写一个字符:fgetc fputc
int fgetc(FILE * stream)
功能:从文件中读取一个字符
参数:stream:文件流
返回值:成功:读到的字符
失败或读到文件末尾:EOF(-1)
int fputc(int c, FILE * stream)
功能:向文件中写入一个字符
参数:c:要写的字符
stream:文件流
返回值:成功:写的字符的ASCII
失败:EOF
#include <stdio.h>
int main(int argc, char const *argv[])
{
//1.打开文件
FILE *fp = fopen("a.txt", "r+");
if (fp == NULL)
{
perror("fopen err");
return -1;
}
printf("fopen success\n");
//读写操作
int ch = fgetc(fp);//h
printf("%d\n", ch);
printf("%c\n", ch);
fputc('a', fp);
ch = fgetc(fp);//l
printf("%d\n", ch);
printf("%c\n", ch);
//关闭文件
fclose(fp);
return 0;
}
例题:用fgetc实现cat功能(cat:将文件内容输出到终端显示)
2)每次读写一串字符 fgets fputs
char * fgets(char *s, int size, FILE * stream);
功能:从文件中每次读取一行字符串
参数:s:存放字符串的地址
size:一次读取的字符个数
stream:文件流
返回值:成功:s的地址
失败或读到文件末尾:NULL
特性:每次实际读取的字符个数为size-1个,会在末尾自动添加\0
每次读一行,遇到\n后不再继续,读下一行
int fputs(const char *s, FILE * stream);
功能:向文件中写字符串
参数:s:要写的内容
stream:文件流
返回值:成功:非负整数
失败:EOF
#include <stdio.h>
int main(int argc, char const *argv[])
{
// 从终端获取
// char buf[32] = {0};
// fgets(buf, 5, stdin);
// //buf:hell\0
// //printf("buf:%s\n", buf);
// fputs(buf, stdout);
//从文件中读
char buf[32] = {0};
FILE *fp = fopen("1hello.c", "r+");
if (fp == NULL)
{
perror("fopen err");
return -1;
}
// 读写
//fgets:读到新的一行,或者读到的个数够了,或者读到文件末尾会结束
fgets(buf, 32, fp); //从文件中读
fputs(buf, stdout); //将内容输出到终端显示
fgets(buf, 32, stdin); //从终端获取内容
fputs(buf, fp); //将内容输出到文件里
//关闭文件
fclose(fp);
return 0;
}
3)二进制读写fread fwrite
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
功能:从文件流读取多个元素
参数: ptr :用来存放读取元素
size :元素大小 sizeof(数据类型)
nmemb :读取元素的个数
stream :要读取的文件
返回值:成功:读取的元素的个数;
读到文件尾: 0
失败: -1
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
功能:按对象写
参数:同上
返回值:成功:写的元素个数
失败 :-1
#include <stdio.h>
int main(int argc, char const *argv[])
{
//1.打开文件
FILE *fp = fopen("a.txt", "w+");
if (fp == NULL)
{
perror("fopen err");
return -1;
}
//2.读写
float arr[3] = {1.23, 4.56, 7.89};
fwrite(arr, sizeof(float), 3, fp);
rewind(fp);//将文件指针定位到文件开头
float data[3] = {0};
fread(data, sizeof(float), 3, fp);
for (int i = 0; i < 3; i++)
printf("%.2f ", data[i]);
putchar(10);
//3.关闭文件
fclose(fp);
return 0;
}
-
- 定位操作:rewind fseek ftell
1)rewind:将文件指针定位到文件开头位置
2)fseek 文件定位操作
3)ftell 获取当前的文件位置(\n也计算在内)
void rewind(FILE *stream);
功能:将文件位置指针定位到起始位置
int fseek(FILE *stream, long offset, int whence);
功能:文件的定位操作
参数:stream:文件流
offset:偏移量:正数表示向后文件尾部偏移,负数表示向文件开头偏移
whence:相对位置:
SEEK_SET:相对于文件开头
SEEK_CUR:相对于文件当前位置
SEEK_END:相对于文件末尾
返回值:成功:0
失败:-1
注:当打开文件的方式为a或a+时,fseek不起作用
long ftell(FILE *stream);
功能:获取当前的文件位置
参数:要检测的文件流
返回值:成功:当前的文件位置,出错:-1
#include<stdio.h>
int main(int argc, char const *argv[])
{
char buf[32]={0};
//打开文件
FILE *fp=fopen("a.txt","w+");
if(fp==NULL)
{
perror("fopen err");
return -1;
}
//读写加定位
//在文件开头写入字符串hello
fputs("hello\n",fp);
//打印当前位置前有多少字符,显示所在当前位置
printf("%ld\n",ftell(fp));
//在当前位置添加字符a
fputc('a',fp);
//在下一行添加字符串world
fputs("\nworld",fp);
//rewind(fp);
fseek(fp,0,SEEK_SET);
fgets(buf,4,fp);
fputs(buf,stdout);
//在当前位置的后五个字符处,添加字符串23081
fseek(fp,5,SEEK_CUR);
fputs("23081",fp);
//在文件末尾位置的前一个位置处添加字符b
fseek(fp,-1,SEEK_END);
fputc('b',fp);
//在当前位置前两个字符处读文件读1个字符打印到终端
fseek(fp,-2,SEEK_CUR);
printf("%c",fgetc(fp));
//统计文件字符个数
fseek(fp,0,SEEK_END);
printf("%ld\n",ftell(fp));
//关闭文件
fclose(fp);
return 0;
}
例题:实现cp命令
diff 文件1,文件2(对比两个文件内容区别)
/*cp复制 */
#include<stdio.h>
int main(int argc, char const *argv[])
{
char buf[32]={};
size_t s;
FILE *fp = fopen(argv[1],"r");
if(fp==NULL)
{
perror("fopen err");
return -1;
}
FILE *fc = fopen(argv[2],"w+");
if(fp==NULL)
{
perror("fopen err");
return -1;
}
//方法1
// while(fgets(buf,32,fp))
// {
// fputs(buf,fc);
// }
//方法2:读多少写多少
while(s = fread(buf,sizeof(char),32,fp))
{
fwrite(buf,sizeof(char),s,fc);
}
fclose(fp);
fclose(fc);
return 0;
}