IO指的是输入输出,输入指的是从外部存储器到内存的流,输出指的是内存到外部存储器的流。输入输出的过程我们用IO函数来进行实现。而IO函数又分为,文件IO函数和标准IO函数。我们今天来学习标准IO函数。在标准IO中我们定义了流和流指针,通过对流和流指针的操作我们就可以对文件进行详细的输入输出操作。下面是今天的xmind
下面来介绍标准IO函数的具体用法:
1.fopen:
功能:打开一个文件,同时在用户空间申请一片缓冲区
原型:
#include <stdio.h>
FILE *fopen(const char *pathname, const char *mode);
参数:
char *pathname:指定要打开的文件的路径以及文件名;
char *mode:打开方式;
r 以读的方式打开文件;
若文件不存在,则函数运行失败;
若文件存在,则运行成功。读取的时候从文件开头读取
r+ 以读写的方式打开文件; 读写的时候从文件开头读写
若文件不存在,则函数运行失败;
若文件存在,则运行成功。读取的时候从文件开头读取
w 以写的方式打开文件,写入的时候从文件开头写入;
若文件不存在,则函数会创建文件并打开;
若文件存在,则会清空文件,并打开文件;
w+ 以读写的方式打开文件,读写的时候从文件开头读写;
若文件不存在,则函数会创建文件并打开;
若文件存在,则会清空文件,并打开文件;
a 以追加写的方式打开文件,写入的时候在文件结尾写入;
若文件不存在,则函数会创建文件并打开;
若文件存在,则打开成功,追加方式写;
a+ 以读和追加写的方式打开文件。
若文件不存在,则函数会创建文件并打开;
若文件存在,则打开成功;
初始位置:读取文件,则初始位置在文件开头
写入文件,则初始位置在文件结尾。
返回值:
成功,返回结构体指针。FILE*
失败,返回NULL,更新errno;
errno:由操作系统提供的变量。
2. perror
功能:根据错误码errno,打印对应的错误信息;
原型:
#include <stdio.h>
void perror(const char *s);
参数:
char *s:用于提示的字符串;
3.fclose
功能:关闭一个文件; 同时释放缓冲区;
原型:
#include <stdio.h>
int fclose(FILE *stream);
参数:
FILE *stream:指定要关闭的文件对应的流指针;
返回值:
成功,返回0;
注意:
4.fprintf
功能:将数据格式化输出到指定的文件中;
原型:
#include <stdio.h>
int printf(const char *format, ...); printf(" hello %d \n", 10);
int fprintf(FILE *stream, const char *format, ...);
参数:
FILE *stream:指定输出到哪个文件中,填对应的流指针即可;
const char *format:格式化字符串,可以填字符,可以填占位符:%d %s %f... 可以填转义字符:\n \r \t \b
...:不定参数,不定数据类型,不定数据个数;
返回值:
成功,返回成功被打印的字节数;
5.fsacnf
功能:从指定文件中格式化获取数据; 与scanf的区别就是,scanf从终端获取,fscanf从文件中获取;
原型:
#include <stdio.h>
int scanf(const char *format, ...); int a; char b; char arr[20]; scanf("%d %c %s", &a, &b, arr);
int fscanf(FILE *stream, const char *format, ...);
参数:
FILE *stream:指定要从哪个文件中获取数据,填对应的流指针;
char *format:格式化字符串, 可以填占位符:%d %s %f...
...:不定参数,不定数据类型,不定数据个数;
返回值:
成功,返回成功获取的数据个数;是个数,不是字节数,其实就是大于0;
失败,返回EOF,同时更新errno;
注意:
6.fputc
功能:将单个字符输出到指定的文件中;
原型:
#include <stdio.h>
int fputc(int c, FILE *stream);
int putchar(int c); putchar('a'); putchar(97);
参数:
int c:指定要输出的字符对应的整型形式,或者字符型形式;
FILE *stream:指定要输出到哪个文件中,填对应的流指针即可;
返回值:
成功,返回成功输出的字符对应的整型形式;
早起的操作系统继承了打字机的习惯,会在文件结尾自动补上\r\n
unix:继承了\r\n
Linux :继承了\n
windows:继承了\r
7.fgetc
功能:从文件中获取单个字符;
原型:
#include <stdio.h>
int fgetc(FILE *stream);
int getchar(void); int c = getchar();
参数:
FILE *stream :;
返回值:
成功,返回成功读取到的字符对应的整型形式;
8.fseek
功能:修改文件偏移量;
原型:
#include <stdio.h>
int fseek(FILE *stream, long offset, int whence);
参数:
FILE *stream:指定要修改哪个文件的偏移量;
long offset:距离whence的偏移量; 想要往后偏移,用正数。如果想要往前偏移,用负数。
int whence:
SEEK_SET, 文件开头位置
SEEK_CUR, 当前位置
SEEK_END, 结尾位置
返回值:
成功,返回0;
失败,返回-1,更新errno;
作业:
1.使用fprintf,fscanf,写一个注册功能。不能重复注册
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, const char *argv[])
{
FILE *p = fopen("./user.txt","r");
char name[10] = "";
char passwd[10];
//账户登录
printf("==============账户登录==============\n");
printf("请输入用户名和密码:\n");
scanf("%s %s",name,passwd);
char arr[6][10];
int i = 0;
while(fscanf(p,"%s",arr[i++]) != EOF);
int n = sizeof(arr)/sizeof(arr[0]);
int type = 0;
for(int j = 0; j < n; j += 2){
if(strcmp(arr[j],name) == 0){
printf("账户验证成功!\n");
type = 1;
if(strcmp(arr[j+1],passwd) == 0){
printf("登录成功!\n");
}
else {
printf("密码错误!\n");
}
break;
}
}
if(type == 0){
printf("账户不存在!是否进行账户注册? y/n\n");
char type2;
getchar();
scanf("%c",&type2);
getchar();
if(type2 == 'y'){
printf("==============账户注册==============\n");
printf("请输入用户名和密码:\n");
scanf("%s %s",name,passwd);
FILE *q = fopen("./user.txt","a+");
fprintf(q,"%s %s",name,passwd);
printf("账户注册成功!\n");
}
else {
return -1;
}
}
return 0;
}
2.计算一个文件有几行,封装成函数,计算一个文件的大小,封装成函数
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void SizeAndLine(FILE *p){
int size = 0;
int line = 0;
while(1){
int c = fgetc(p);
if(-1 == c){
break;
}
size ++;
if('\n' == c){
line ++;
}
}
printf("大小 = %d,行数 = %d\n",size,line);
}
int main(int argc, const char *argv[])
{
FILE *p = fopen(argv[1],"r");
if(NULL == p){
perror("fopen");
return -1;
}
SizeAndLine(p);
return 0;
}