/*
文件的顺序读写:
功能 函数名 适用于
字符输入函数 fgetc 所有输入流
字符输出函数 fputc 所有输出流
文本行输入函数 fgets 所有输入流
文本行输出函数 fputs 所有输出流
格式化输入函数 fscanf 所有输入流
格式化输出函数 fprintf 所有输出流
//以上都是文本
二进制输入 fread 文件
二进制输出 fwrite 文件
程序--(具体如何w的代码)-> 流 --(c语言底层实现)-> 外部硬盘
何为流?(介于内存与外部设备之间的)
//
//打开一个文件会返回一个FILE*类型的指针
//这个FILE*类型的指针就可以称为文件流
//
// 读写文件时需要打开与关闭文件
//但是printf和scanf则不需要打开或关闭键盘或屏幕,为什么呢?
// 任何一个C语言程序,只要运行起来就会默认打开3个流
// stdin FILE*类型 标准输入流(键盘)
// stdout FILE*类型 标准输出流(屏幕)
// stderr FILE*类型 标准错误流(屏幕)
printf("%s\n",arr);
fprintf(stdout,"%s\n",arr);//两者等价
文件也是资源,一个程序打开文件的个数是有限的,不是无限打开的,所以需要关闭文件
不及时关闭文件,有可能会丢失数据
//"w"写文件的时候,他会把文件的内容情况,然后写
"w"文件的时候,若是没有该文件,会自动创建,"r"不行
//每次写单个数据
int fputc ( int character, FILE * stream );
character:ascall值
如果成功,则返回所写的字符
每次读单个数据
int fgetc ( FILE * stream );
//如果读失败,返回EOF
------------------------------
*/
/*
写一行数据
int fputs ( const char * str, FILE * stream );
成功返回非负值,失败返回EFO
读一行数据
char * fgets ( char * str, int num, FILE * stream );
从流中读取字符,并将其作为C字符串存储到str中,直到读取(num-1)个字符,
或者到达换行符或文件结束符,以先发生的为准。
换行符使fgets停止读取,但它被函数认为是一个有效字符,并包含在复制到str的字符串中。
在复制到str的字符之后,将自动追加一个终止null字符。
请注意,fgets与gets有很大的不同:fgets不仅接受流参数,而且允许指定str的最大长度,
并在字符串中包含任何结束换行符。
str指向字符数组的指针,在该数组中复制所读的字符串。
num在要复制到str中的最大字符数(包括结束的空字符)。
num = (num-1)个字符 + null('\0')字符 '\n'等字符也算一个字符
stream指向标识输入流的FILE对象的指针。
可以用作从标准输入中读取的参数。
如果成功:返回str;
读取失败:返回NULL
-----------
*/
/*
格式化的数据的输入与输出
输出
fprintf(pf,"%s %d\n", next.name);
与printf对比
输入
int fscanf ( FILE * stream, const char * format, ... );
类比scanf
-----------------------------
*/
文件的写
int main()
{
//文件的打开
FILE* pf = fopen("test.txt", "w");
if (pf == NULL)
{
printf("%s\n", strerror(errno));
return 1;
}
//写文件
fputc('a', pf);
char i = 'a';
for (i = 'a'; i <= 'z'; i++)
{
fputc(i,pf);
}
//关闭文件
fclose(pf);
pf = NULL;
return 0;
}
文件的读
int main()
{
FILE* pf = fopen("test.txt", "r");
if (pf == NULL)
{
printf("%s\n", strerror(errno));
return -1;
}
//int i = 0;
char ch = 0;
//for (i = 0; i < 27; i++)
//{
// ch = fgetc(pf);
// printf("%c ", ch);
//}
while ((ch = fgetc(pf)) != EOF)
{
printf("%c ", ch);
}
printf("\n");
fclose(pf);
pf = NULL;
return 0;
}
文件的写一行
int main()
{
//文件的打开
FILE* pf = fopen("test.txt", "w");
if (pf == NULL)
{
printf("%s\n", strerror(errno));
return 1;
}
//写文件
fputs("abcdefg\n", pf);
fputs("abcdefg\n", pf);
//关闭文件
fclose(pf);
pf = NULL;
return 0;
}
文件的读一行
int main()
{
FILE* pf = fopen("test.txt", "r");
if (pf == NULL)
{
/* printf("%s\n", strerror(errno));*/
perror("fopen");
return -1;
}
char ch[10] = "0";
fgets(ch,10,pf);
printf("%s\n", ch);
fclose(pf);
pf = NULL;
return 0;
}
输出格式化的数据
struct S
{
char name[20];
int age;
float score;
};
typedef struct S S;
int main()
{
S jack = { "jack",25,99.5f };
FILE* pf = fopen("test.txt", "w");
if (pf == NULL)
{
perror("fopen");
return 1;
}
fprintf(pf,"%s\n%d\n%.2lf\n",jack.name,jack.age,jack.score);
fclose(pf);
pf = NULL;
return 0;
}
输入格式化的数据
struct S
{
char name[20];
int age;
float score;
};
typedef struct S S;
int main()
{
S jack = { 0 };
FILE* pf = fopen("test.txt", "r");
if (pf == NULL)
{
perror("fopen");
return 1;
}
//读取的时候遇到空格或\n 结束
fscanf(pf, "%s\n%d\n%f\n", jack.name, &jack.age, &jack.score);
printf("%s\n%d\n%f\n", jack.name, jack.age, jack.score);
fclose(pf);
pf = NULL;
return 0;
}
/*
二进制输入
fread 文件
size_t fread ( void * ptr, size_t size, size_t count, FILE * stream );
将读到的数据存储在ptr指向的内存块中
二进制输出
fwrite 文件
size_t fwrite ( const void * ptr, size_t size, size_t count, FILE * stream );
ptr:只要要输出的内容的起始地址
size:输出的个数
count:输出的每个个数的大小
--------------
*/
二进制写
struct S
{
char name[20];
int age;
float score;
};
int main()
{
struct S s = { "zhangsan",50,50.5f };
//以二进制的形式写入文件中
FILE* pf = fopen("test.txt", "wb");
if (pf == NULL)
{
perror("fopen");
return 1;
}
fwrite(&s, sizeof(struct S), 1, pf);
fclose(pf);
pf = NULL;
return 0;
}
二进制读
struct S
{
char name[20];
int age;
float score;
};
int main()
{
struct S s = { 0 };
//以二进制的形式写入文件中
FILE* pf = fopen("test.txt", "rb");
if (pf == NULL)
{
perror("fopen");
return 1;
}
fread(&s, sizeof(struct S), 1, pf);
fprintf(stdout, "%s %d %f", s.name, s.age, s.score);
fclose(pf);
pf = NULL;
return 0;
}