1.什么是io
输入和输出。
stdio就是标准输入输出
2.fopen
FILE *fopen(const char *pathname, const char *mode);
参数mode:
w:只写打开,无文件,创建;有文件,清空;光标在开头
r: 只读打开
w+:以可读可写的形式打开文件。其他属性和 w 一样
r+:以可读可写的形式打开文件。其他属性和r一样
a: 追加写打开,无文件,创建,有文件,光标在结尾
a+:可读+追加写,无文件,创建,有文件,读,光标在头,写,光标在尾
返回值:返回成功打开的文件的指针,文件打开失败,返回空指针NULL
注意及时关闭 fclose
3.fprintf
int fprintf(FILE *stream, const char *format, ...);
功能描述:将format的内容,写入到stream文件指针(通过fopen获取)指向的文件中去,实现的效果就是将内容写入到文件中去
注意:会覆盖
int sprintf(char *str, const char *format, ...)
功能描述:将format的内容,写入到str所指向的字符数组中,
任意类型的数据 ====>字符串类型
4.fscanf
int fscanf(FILE *stream, const char *format, ...);
功能描述:从stream指向的文件中,读取内容,写入format中格式占位符代表的变量中去
具体见下面练习
5.三个特殊的FILE*文件指针
1:stdin 标准输入流
2:stdout 标准输出流
3:stderr 标准错误流
6.#include <error.h>
在头文件 #include 里面,申明了一个全局变量 errno
当任何系统函数,调用发生错误的时候,就会修改errno的值,我们很多时候需要通过errno具体的错误信息,去定位错误原因
但是注意:errno是一个int类型的数据,如果直接输出errno的话,我们会得到一个1~n的整数
void perror(const char *s);
功能描述:在终端上输出 "s:errno对应的错误信息"(常用)
7.fputc 和 fgetc
int fputc(int c, FILE *stream);
功能描述:将c看做ASCII码,他所代表的字符,写入stream所指向的文件中去
返回值:成功,返回成功写入的字符,注意是以unsigned char形式返回,失败返回 EOF
int fgetc(FILE *stream)
功能描述:从stream指向的文件中,读取1个字符,并返回
返回值:成功,返回成功读取的字符,注意是以unsigned char形式返回,失败返回 EOF
练习
// 申请该结构体数组,容量为5,初始化5个学生的信息
// 使用fprintf将数组中的五个学生信息,保存到文件中去
#include <stdio.h> #include <string.h> #include <errno.h> // 申请该结构体数组,容量为5,初始化5个学生的信息 // 使用fprintf将数组中的五个学生信息,保存到文件中去 typedef struct Student { char name[16]; int age; double math_score; double chinese_score; double english_score; double physics_score; double chemistry_score; double bio_score; } STU_STRUCT; int main(int argc, char const *argv[]) { STU_STRUCT s1 = {"张三", 14, 89, 99, 79, 67, 56, 93}; STU_STRUCT s2 = {"李四", 15, 88, 98, 78, 66, 55, 92}; STU_STRUCT s3 = {"王五", 16, 87, 97, 77, 65, 54, 93}; STU_STRUCT s4 = {"赵六", 17, 86, 96, 76, 64, 53, 99}; STU_STRUCT s5 = {"田七", 18, 85, 95, 75, 63, 52, 97}; STU_STRUCT student_arr[5] = {s1, s2, s3, s4, s5}; FILE *fp; if ((fp = fopen("./StudentScore", "w")) == NULL) { perror("打开./StudentScore失败"); return -1; } for (int i = 0; i < (sizeof(student_arr)/sizeof(STU_STRUCT)); i++) { fprintf(fp, "%s\t", student_arr[i].name); fprintf(fp, "%d\t",student_arr[i].age); fprintf(fp, "%.2f\t",student_arr[i].math_score); fprintf(fp, "%.2f\t",student_arr[i].chinese_score); fprintf(fp, "%.2f\t",student_arr[i].english_score); fprintf(fp, "%.2f\t",student_arr[i].physics_score); fprintf(fp, "%.2f\t",student_arr[i].chemistry_score); fprintf(fp, "%.2f\n",student_arr[i].bio_score); } fclose(fp); return 0; }
// 下一次程序运行的时候,使用fscanf,将文件中的五个学生信息,写入
// (加载)到数组中去,并直接输出学生信息
#include <stdio.h> #include <string.h> #include <errno.h> // 下一次程序运行的时候,使用fscanf,将文件中的五个学生信息,写入 // (加载)到数组中去,并直接输出学生信息 typedef struct Student { char name[16]; int age; double math_score; double chinese_score; double english_score; double physics_score; double chemistry_score; double bio_score; } STU_STRUCT; int main(int argc, char const *argv[]) { STU_STRUCT student_arr[10] = {}; FILE *fp; if ((fp = fopen("./StudentScore", "r")) == NULL) { perror("打开./StudentScore失败"); return -1; } for (int i = 0; i < 10; i++) { if (fscanf(fp, "%s\t%d\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf", student_arr[i].name, &student_arr[i].age, &student_arr[i].math_score, &student_arr[i].chinese_score, &student_arr[i].english_score, &student_arr[i].physics_score, &student_arr[i].chemistry_score, &student_arr[i].bio_score ) == EOF) { printf("循环结束了\n"); break; }else{ printf("循环开始"); printf("第%d条:%s %d %.2lf %.2lf %.2lf %.2lf %.2lf %.2lf\n", i+1, student_arr[i].name, student_arr[i].age, student_arr[i].math_score, student_arr[i].chinese_score, student_arr[i].english_score, student_arr[i].physics_score, student_arr[i].chemistry_score, student_arr[i].bio_score ); } } fclose(fp); return 0; }
循环开始第1条:张三 14 89.00 99.00 79.00 67.00 56.00 93.00 循环开始第2条:李四 15 88.00 98.00 78.00 66.00 55.00 92.00 循环开始第3条:王五 16 87.00 97.00 77.00 65.00 54.00 93.00 循环开始第4条:赵六 17 86.00 96.00 76.00 64.00 53.00 99.00 循环开始第5条:田七 18 85.00 95.00 75.00 63.00 52.00 97.00