IO接口分为标准IO(库函数)和文件IO(系统调用)
一、系统IO接口函数(库函数)
系统调用(posix):系统调用就是从用户空间进入到内核空间的一个过程,操作系统的类型不同,系统调用的接口也不同,效率低,只要系统调用发生,就要调用一次内核。
库函数(ANSI C):库函数是相当于系统调用+缓冲区实现的,可以移植性很强,几乎在所有的操作系统上都可以使用,库函数的执行的效率很高。
1.fopen的用法
fopen是标准IO中的一个打开文件的函数接口
FILE *fopen(const char *pathname, const char *mode);
功能:打开一个文件
#include <stdio.h>
参数:
@pathname:文件的路径及文件的名字(字符指针)
@mode:打开文件的方式
r:以只读的方式打开文件,将光标定位在文件的开头
r+以读写的方式打开文件,将光标定位在文件的开头
w:以只写的方式打开文件,如果文件不存在创建文件,如果文件存在清空文件,将光标定位在文件的开头
w+:以读写的方式打开文件,如果文件不存在创建文件,如果文件存在清空文件,将光标定位在文件的开头
a:以只写的方式打开文件,如果文件不存在就创建,如果文件存在将光标定位在文件的结尾
a+:以读写的方式打开文件,如果文件不存在就创建,如果文件存在写在结尾写,如果文件存在读在开头读
返回值:成功返回FILE的指针,失败返回NULL,置位错误码
注:在一个正在运行的程序中默认已经产生三个FILE结构体了
stdin :标准输入
stdout:标准输出
stderr :标准出错
2.fclose的用法
int fclose(FILE *stream);
功能:关闭文件
#include <stdio.h>
参数:
@stream:文件指针
返回值:成功返回0,失败返回-1(EOF),置位错误码
示例:
#include <stdio.h>
int main(int argc, char const *argv[])
{
FILE *fp;
//以只写的方式打开文件,如果文件不存在就创建文件
//“./test.txt”文件的路径和文件的名字
//"w" 权限
fp = fopen("./test.txt","w");
if(fp == NULL){
printf("open file error\n");
return -1;
}
printf("open file success\n");
//关闭文件
if(fclose(fp)){
printf("close file error\n");
return -1;
}
fclose(stdin);
fclose(stdout);
fclose(stderr);
return 0;
}
3.strerror函数使用
错误码:应用程的fopen函数会调用底层的sys_open函数,sys_open执行失败的时候将错误码传递给程序的errno的变量,可以通过这个变量获取到底层的错误。
char *strerror(int errnum);
功能:根据错误码,转换出来错误信息
#include <string.h>
参数:
@errnum:错误码
返回值:错误信息
4.perror函数
void perror(const char *s);
功能:直接打印错误信息 (自动加上'\n')
#include <stdio.h>
参数:
@s:用户附加的错误信息
返回值:无
示例:
#include<stdio.h>
//#include<errno.h>
//extern int errno;
int main(int argc, char const *argv[])
{
FILE *fp;
fp = fopen("./text.txt","r");
if(fp==NULL){
//printf("open file:%s\n",strerror(errno));
perror("open file error");
return -1;
}
printf("open file success\n");
return 0;
}
5.fgetc/fputc函数使用
int fgetc(FILE *stream);
功能:从文件中读取一个字符
参数:
@stream:FILE的结构体指针
返回值:成功返回读取到字符的ascii码,失败返回EOF(-1)
int fputc(int c, FILE *stream);
功能:向文件中写一个字符
参数:
@c:被写的字符
@stream:FILE指针
返回值:成功返回读取到字符的ascii码,失败返回EOF(-1)
示例:使用fgetc和fputc实现一个cp命令
#include <stdio.h>
#define PRINT_ERR(msg) do{ \
perror(msg);\
return -1;\
}while(0)
int main(int argc, char const *argv[])
{
FILE *sfp,*dfp;
char ch;
//1.参数检查
if(argc != 3){
printf("input error,try again\n");
printf("usage: ./a.out srcfile destfile\n");
return -1;
}
//2.打开文件
if((sfp = fopen(argv[1],"r")) == NULL)
PRINT_ERR("open srcfile error");
if((dfp = fopen(argv[2],"w")) == NULL)
PRINT_ERR("open destfile error");
//3.完成拷贝
while((ch = fgetc(sfp))!=EOF)
fputc(ch,dfp);
//4.关闭文件
fclose(sfp);
fclose(dfp);
return 0;
}
6.fgets/fputs用法
char *fgets(char *s, int size, FILE *stream);
功能:从stream中读取字符串到s,读取的大小最大比size小1.
遇到EOF或者'\n'结束,如果是遇到'\n'结束,会将这个字符也写入到s
参数:
@s:缓冲区的首地址
@size:读取的大小
@Steam:文件指针
返回值:成功返回s,失败或者EOF会返回NULL
int fputs(const char *s, FILE *stream);
功能:将s中的字符串写入到stream中
参数:
@s:缓冲区的首地址
@stream:文件指针
返回值:成功返回写入字符的个数,失败返回EOF
示例:使用fgets/fputs实现拷贝文件的过程
#include <head.h>
int main(int argc, char const *argv[])
{
FILE*fp1,*fp2;
char buf[10] = {0};
if(argc != 3){
printf("input error,try again\n");
printf("usage:./a.out srcfile destfile\n");
return -1;
}
if((fp1 = fopen(argv[1],"r"))==NULL)
PRINT_ERR("open file error");
if((fp2 = fopen(argv[2],"w"))==NULL)
PRINT_ERR("open file error");
while(fgets(buf,sizeof(buf),fp1) != NULL){
fputs(buf,fp2);
}
fclose(fp1);
fclose(fp2);
return 0;
}
//头文件程序
#ifndef __HEAD_H__
#define __HEAD_H__
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define PRINT_ERR(msg) do{ \
perror(msg);\
return -1;\
}while(0)
#endif
7.fprintf/sprintf/snprintf用法
int fprintf(FILE *stream, const char *format, ...);
功能:向指定的文件指针中输出信息(格式化(字符串)输出)