根据数据的组织形式,数据文件被称为文本文件或者二进制文件。
1.数据在内存中以二进制的形式存储,如果不加转换的输出到外存,就是二进制文件。
2.如果要求在外存上以ASCII码的形式存储,则需要在存储前转换。以ASCII字符的形式存储的文件就是文本文件。
一个数据在内存中是怎么存储的呢?
字符一律以ASCII形式存储,数值型数据既可以用ASCII形式存储,也可以使用二进制形式存储。
如有整数10000,如果以ASCII码的形式输出到磁盘,则磁盘中占用5个字节(每个字符一个字节),而二进制形式输出,则在磁盘上只占4个字节(VS2013测试)。
测试代码:
int main()
{
int a = 10000;
FILE* pa = fopen("bin.bat", "wb");
if (pa == NULL)
{
printf("%s\n", strerror(errno));
return 1;
}
else
{
fwrite(&a, sizeof(int), 1, pa);
printf("文件写入成功!\n");
fclose(pa);
pa = NULL;
}
return 0;
}
#define _CRT_SECURE_NO_WARNINGS 1
#include
#include
#include
#include
int main() //输入缓冲区的理解
{
FILE* pa = fopen("data.txt", "w"); //打开文件
if (pa == NULL)
{
printf("%s\n", strerror(errno));
}
else //写进文件
{
fputs("abcde", pa);
printf("睡眠10s,写进缓冲区的数据!\n");
Sleep(10000);
fflush(pa); //注意fflush在vs高的版本不能使用
printf("在睡眠10s,此时打开data.txt文档,就有数据!\n");
Sleep(10000);
}
fclose(pa);
pa = NULL; //关闭文件
return 0;
}
代码如下:
#define _CRT_SECURE_NO_WARNINGS 1
#include
#include
#include
//int main() //文件操作的相关问题
//{
// //fopen函数如果是以写的形式打开
// //如果文件不存在,会创建这个文件
// //如果文件存在,会清空文件的内容
// //fopen函数如果是以读的形式打开
// //文件不存在则文件打开失败
// FILE* pa = fopen("data.txt", "r"); //Opens for reading. If the file does not exist or cannot be found, the fopen call fails.
// //FILE* pa = fopen("data.txt", "w"); //Opens an empty file for writing. If the given file exists, its contents are destroyed.
// if (pa == NULL)
// {
// printf("文件打开失败!\n");
// printf("%s\n", strerror(errno));
// return 1; //失败返回
// }
// else
// {
// int i = 0;
// for (i = 'a'; i <= 'z'; i++)
// {
// fputc(i , pa);
// }
// printf("写入文件成功!\n");
// }
// //读写文件
// fclose(pa); //关闭文件
// pa = NULL;
// return 0;
//}
// 相对路径
// ../表示上一级目录
// ./当前目录
// ./文件夹//.txt 下一级路径
// ../../上上级目录
// 绝对路径 从根目录开始写的路径 D:\visua stdio 2013代码\文件操作的相关问题\文件操作的相关问题
int main() //fgetc适合于所以输入流
{
//打开文件
FILE* pa =fopen("data.txt", "r");
if (pa == NULL)
{
printf("文件打开失败!\n");
printf("%s\n", strerror(errno));
return 1;
}
//读取文件
/*int ch = fgetc(pa);
printf("%c\n", ch);*/
int ch = 0;
while ((ch = fgetc(pa)) != EOF)
{
printf("%c", ch);
}
printf("\n");
//关闭文件
fclose(pa);
pa = NULL;
return 0;
}
//int main() 补充,键盘上输入,其中getchar()putchar()只能从键盘上输入,屏幕上输出,适用于标准输入、输出函数
//{
// int ch = 0;
// while ((ch = fgetc(stdin)) != EOF)
// {
// printf("%c\n", ch);
// }
// return 0;
//}
代码如下:
#define _CRT_SECURE_NO_WARNINGS 1
#include
#include
#include
//int main() //fputs文本行输出流函数
//{
// FILE* pa = fopen("data.txt", "w");
// if (pa == NULL)
// {
// printf("文件打开失败!\n");
// printf("%s\n", strerror(errno));
// }
// else
// {
// //写一行数据
// fputs("bit education\n", pa);
// fputs("bit NB\n", stdout);//文本行打印到屏幕上
// printf("文件写入成功!\n");
// }
// fclose(pa);
// pa = NULL;
// return 0;
//}
int main() //fgets适用于所有输入流
{
char arr[100] = {
0 };
FILE* pa = fopen("data.txt", "r");
if (pa == NULL)
{
printf("打开文件失败!\n");
printf("%s\n", strerror(errno));
return 1;
}
else
{
//读一行数据
fgets(arr, 6, pa); //其中bit3个字符再包括一个\0就是4个字符,\0是字符串结束标志
printf("%s\n", arr);
printf("文件读入成功!\n");
//读多行数据
/* while (fgets(arr, 4, pa) != NULL)
{
printf("%s", arr);
}*/
//也可以从屏幕上输入,标准输入流读取
/*fgets(arr, 4, stdin);*/
printf("%s", arr);
printf("\n");
}
return 0;
}
代码如下:
#define _CRT_SECURE_NO_WARNINGS 1
#include
#include
#include
struct stu
{
char name[20];
int age;
float score;
};
//int main() //fprintf的相关问题
//{
// struct stu s = { "鱼王", 20, 66.5f };
// struct stu* pb = &s;
// FILE* pa = fopen("data.txt", "w"); //打开文件
// if (pa == NULL)
// {
// printf("%s\n", strerror(errno));
// return 1;
// }
// else //格式化的写入文件
// {
// fprintf(pa, "%s %d %f", pb->name, pb->age, pb->score);
// printf("文件写入成功!\n");
// //printf("%s %d %f\n", s.name, s.age, s.score);
// }
// fclose(pa); //关闭文件
// pa = NULL;
// return 0;
//}
int main() //fscanf的相关问题
{
struct stu s = {
0 };
struct stu* pb = &s;
FILE* pa = fopen("data.txt", "r");
if (pa == NULL)
{
printf("%s\n", strerror(errno));
return 1;
}
else //格式化的读取文件,fscanf在文件流上读取数据到文件中在printf打印输送到屏幕上
{
fscanf( pa,"%s%d%f", pb->name, &(pb->age), &(pb->score));
//fscanf( stdin, "%s%d%f", pb->name, &(pb->age), &(pb->score)); //也可以从键盘上读取
printf("%s %d %f\n", s.name, s.age, s.score);
//fprintf(stdout, "%s %d %f\n", s.name, s.age, s.score);
}
fclose(pa);
pa = NULL;
return 0;
}
1.scanf、printf适用于标准的输入输出流的格式化输入输出语句。
2.fscanf、fprintf适用于所有的标准输入输出流的格式化输入输出语句。
3.sscanf、sprintf可以把结构化的数据转化为字符串,也可以把字符串中读取格式化的数据。
格式化数据的定义:某种数据的格式。
代码如下:
#define _CRT_SECURE_NO_WARNINGS 1
#include
#include
#include
int main() //fseek的相关问题,根据文件指针的位置和偏移量来定位文件指针。
{
FILE* pa = fopen("data.txt", "r");
if (pa == NULL)
{
printf("%s\n", strerror(errno));
}
else
{
int ch = 0;
/*ch = fgetc(pa);
printf("%c\n", ch);
ch = fgetc(pa);
printf("%c\n", ch); */
//fseek根据文件指针的位置和偏移量来定位文件指针。
//fseek(pa,0, SEEK_CUR);//流,SEEK_CUR文件当前位置 ,起始位置偏移两个字节
//fseek(pa,0, SEEK_SET); //流,SEEK_SET文件起始位置,起始位置就是a
//fseek(pa, -3, SEEK_END); //流,SEEK_END文件结束标志,结束标志是\0,所以当offset为0 时,读取到的是\0
/*ch = fgetc(pa);
printf("%c\n", ch);*/
//rewind(pa); //rewind让文件指针的位置回到文件的起始位置
//printf("%d\n", ftell(pa)); //ftell返回文件指针相对于起始位置的偏移量
//printf("%c\n", ch);
while ((ch = fgetc(pa)) != EOF)
{
printf("%c ", ch);
}
printf("\n");
if (ferror(pa))
{
printf("读取时发生错误,失败而结束!\n");
}
else if (feof(pa))
{
printf("遇到文件末尾结束!\n");
}
}
fclose(pa);
pa = NULL;
return 0;
}
//下面文件结束的注意事项
当我们使用fgetc读取的时候,1.发生错误结束了 2.读取到文件末尾结束了 EOF结束
当我们使用fgets读取的时候 1.发生错误结束啦 2.读取到文件末尾结束了 NULL结束
当我们使用fread发现实际读取的个数小于要求读取的最大个数 例如要求读取5个,实际读取4个就结束了
文件结束判定
被错误使用的 feof
牢记:在文件读取过程中,不能用feof函数的返回值直接用来判断文件的是否结束。
而是应用于当文件读取结束的时候,判断是读取失败结束,还是遇到文件尾结束。
1. 文本文件读取是否结束,判断返回值是否为EOF (fgetc),或者NULL(fgets)
例如:
fgetc判断是否为EOF.
fgets判断返回值是否为NULL.
2. 二进制文件的读取结束判断,判断返回值是否小于实际要读的个数。
例如:
fread判断返回值是否小于实际要读的个数。
以上就是今天要讲的内容,本文仅仅简单介绍了C语言中部分文件操作的用法,文件能使我们便捷地保存数据,不会让数据丢失。另外,如果上述有任何问题,请懂哥指教,不过没关系,主要是自己能坚持,更希望有一起学习的同学可以帮我指正,但是如果可以请温柔一点跟我讲,爱与和平是永远的主题,爱各位了。