基本的文件操作
只有“w”和“a”才能创建文件
1、C语言操作文件三步:1、打开文件2、读写文件3、关闭文件
个人理解,文件指针实质上时一个结构体指针,里面包含多个成员变量
#include <stdio.h>
int main()
{
int ar[] = { 12,23,34,45,56,78,89,90 };
int n = sizeof(ar) / sizeof(ar[0]);
FILE* fp = NULL;//定义文件流指针
errno_t tag = NULL;//
tag= fopen_s(&fp,"yhp.txt", "w");//打开文件函数,里面的参数为(文件指针地址,文件名路径,操作文件模式)令文件流指针指向这个文件
//注意vs2012里面和vs2019里面的此函数参数不一样,只有两个参数
if (NULL == fp)
{
printf("file open error");
return 1;
}
for (int i = 0; i < n; i++)
{
fprintf_s(fp, "%d ", ar[i]);//三个参数(文件指针,控制格式,要输出的数据),也就是说从ar里面取出来的数据传到fp指向的文件中
printf("%d ", ar[i]);//实际上就是fprintf_s(stdout, "%d ", ar[i]);也就是说从ar中输出的数据传到了标准输出设备中去了
printf("\n");
fprintf_s(stdout, "%d ", ar[i]);//printf就是调用了此函数
}
fclose(fp);//操作完之后要将文件指针释放,也就是关闭文件,原因是,在写入数据时,文件指针会打开文件流对象,数据先写入缓存缓存,
//而文件未关闭之前写入的数据还会留在缓冲区,关闭之后才会回收文件流对象,释放缓存,数据进入文件
//不同系统会有不同的缓存,有的文件流对象没有缓存
fp = NULL;//关闭文件后将文件指针置空,防止变成野指针
return 0;
}
fclose(fp);
创建的文件会保存在项目中。
操作完之后要将文件指针释放,也就是关闭文件,原因是,在写入数据时,文件指针会打开文件流对象,数据先写入缓存缓存,而文件未关闭之前写入的数据还会留在缓冲区,关闭之后才会回收文件流对象,释放缓存,数据进入文件,不同系统会有不同的缓存,有的文件流对象没有缓存。
2、数据存储进文件的方式
如int ar[]={12,23,34,45,56};
写入文件后就会以文本形式存入文件,这里会用到atoi 和itoa函数
在调用fprintf_s(fp, "%d ", ar[i]);时,存储格式为1Ascll码值为49,转换为二进制为0011 0001一般用十六进制显示为31
因此,12 存储时会调用itoa函数表示为 31 32 20分别代表‘1’ ‘2‘ ’ ‘,1,2,和空格,然后在文件中显示。(可以以文本形式打开,也可以是二进制…)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AEq6Rmg3-1631712200558)(C:\Users\刘锦\AppData\Roaming\Typora\typora-user-images\image-20210822165705398.png)]
可以把文本文件添加到资源文件中以二进制形式打开,就会出现上图;类似的double,char,float,也是如此。
3、绝对路径,相对路径
绝对路径就是所谓的文件夹,相对路径就是文件夹里面的东西;
如果不存在绝对路径,“w”不会自动创建
#include <stdio.h>
int main()
{
int ar[] = { 12,23,34,45,56,78,89,90 };
int n = sizeof(ar) / sizeof(ar[0]);
FILE* fp = NULL;//定义文件流指针
errno_t tag = NULL;//
tag = fopen_s(&fp, "E:\\Liujin\\liujin.txt", "w");//注意,这里有两个\\或者一个/也可以,因为一个'\'代表转义字符,两个才代表'\'
if (NULL == fp)
{
printf("file open error");
return 1;
}
for (int i = 0; i < n; i++)
{
fprintf_s(fp, "%d ", ar[i]);
printf("%d ", ar[i]);
fprintf_s(stdout, "%d ", ar[i]);
}
fclose(fp);
fp = NULL;
return 0;
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IWeHW5PS-1631712200559)(C:\Users\刘锦\AppData\Roaming\Typora\typora-user-images\image-20210822173021357.png)]
由于给的绝对路径不存在,因此fp为空,所以printf文件打开失败
4、读操作
int Save()
{
int ar[] = { 12,23,34,45,56,78,89,90 };
int n = sizeof(ar) / sizeof(ar[0]);
FILE* fp = NULL;//定义文件流指针
errno_t tag = NULL;//
tag= fopen_s(&fp,"yhp.txt", "w");//打开文件函数,里面的参数为(文件指针地址,文件名路径,操作文件模式)令文件流指针指向这个文件
//注意vs2012里面和vs2019里面的此函数参数不一样,只有两个参数
if (NULL == fp)
{
printf("file open error");
return 1;
}
for (int i = 0nt i = 0; i < 10; i++)
; i < n; i++)
{
Insert_Prev(p, p->head,i+1);
PrintDuList(p);
}
}
{
fprintf_s(fp, "%d ", ar[i]);//三个参数(文件指针,控制格式,要输出的数据),也就是说从ar里面取出来的数据传到fp指向的文件中
printf("%d ", ar[i]);//实际上就是fprintf_s(stdout, "%d ", ar[i]);也就是说从ar中输出的数据传到了标准输出设备中去了
fprintf_s(stdout, "%d ", ar[i]);//printf就是调用了此函数
}
fclose(fp);//操作完之后要将文件指针释放,也就是关闭文件,原因是,在写入数据时,文件指针会打开文件流对象,数据先写入缓存缓存,
//而文件未关闭之前写入的数据还会留在缓冲区,关闭之后才会回收文件流对象,释放缓存,数据进入文件
//不同系统会有不同的缓存,有的文件流对象没有缓存
fp = NULL;//关闭文件后将文件指针置空,防止变成野指针
return 0;
}
int main()
{
Save();
int br[10] = {};
FILE* fp = NULL;
errno_t tag = fopen_s(&fp, "yhp.txt", "r");
if (NULL == fp)
{
return(1);
}
for (int i = 0; i < 10; i++)
{
//sprintf_s(buffer, 10, "%d ", &buffer[i]);从缓冲区读取,然后存放到buffer里
//scanf_s("%d ", &ar[i]);//stdin中读取,fscanf_s(fp, "%d ", &ar[i]);将键盘。,鼠标之类的也会看作文件
fscanf_s(fp, "%d", &br[i]);
//从fp指向的文件中读取,存储到br中,将文件中存储的ascll码值转换为整型,遇见空格就停止读,会用到atoi函数
//因此在写操作的时候一定要记得加空格或者其他控制符隔开,要不然会当作一个整体来读
}
fclose(fp);
fp = NULL;
for (int i = 0; i < 10; i++)
{
printf("%d ", br[i]);
}
return 0;
}
5、二进制写“wb”
#include <stdio.h> int main() { int ar[] = { 12,23,34,45,56,78,89,90 }; int n = sizeof(ar) / sizeof(ar[0]); FILE* fp = NULL;//定义文件流指针 errno_t tag = NULL; tag = fopen_s(&fp, "liujin.txt", "wb"); if (NULL == fp) { printf("file open error"); return 1; } fwrite(ar, sizeof(int), n, fp);//专门的二进制写操作,参数为要读取的数组,元素的大小,元素的个数,文件指针 fclose(fp); fp = NULL; return 0; }
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MoYkBUJz-1631712200560)(C:\Users\刘锦\AppData\Roaming\Typora\typora-user-images\image-20210823104021454.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-T1kCPcqV-1631712200561)(C:\Users\刘锦\AppData\Roaming\Typora\typora-user-images\image-20210823104646790.png)]
可以看出二进制写是将整个数字以二进制的形式存储,然后以文本的方式显示出来。二单纯的写文件则是将每一个数字以ascll码值存放,然后以文本形式显示。
6、二进制读
int main() { int ar[] = { 97,98,99,100,101,102,103,104 }; int n = sizeof(ar) / sizeof(ar[0]); FILE* fp = NULL;//定义文件流指针 errno_t tag = fopen_s(&fp, "liujin.txt", "rb");; if (NULL == fp) { printf("file open error %d",tag); return 1; } fread(ar,sizeof(int),n,fp);//专门的二进制读操作,参数为要存放数据的数组,元素的大小,元素的个数,文件指针 fclose(fp); fp = NULL; return 0; }
7、末尾只写
#include<stdio.h> int main() { int ar[10] = { 12,23,34,45,56,67,78,89,90,100}; int n = sizeof(ar) / sizeof(ar[0]); FILE* fp = NULL; errno_t tag = fopen_s(&fp, "liujin.txt", "a"); if (fp == NULL) { printf("open file false!"); return 1; } for (int i = 0; i < n; i++) { fprintf_s(fp, "%d ", ar[i]); } fclose(fp); fp = NULL; return 0; }
8、文件位置
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IN3fkMcM-1631712200561)(C:\Users\刘锦\AppData\Roaming\Typora\typora-user-images\image-20210823203733994.png)]
long ftell()
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qCkM6Lux-1631712200564)(C:\Users\刘锦\AppData\Roaming\Typora\typora-user-images\image-20210823204758021.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RS11MY9g-1631712200565)(C:\Users\刘锦\AppData\Roaming\Typora\typora-user-images\image-20210823204844908.png)]
feeek()
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-n23wtPOG-1631712200565)(C:\Users\刘锦\AppData\Roaming\Typora\typora-user-images\image-20210823205904904.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7Xtmlk1r-1631712200566)(C:\Users\刘锦\AppData\Roaming\Typora\typora-user-images\image-20210823211542788.png)]
rewind(fp);//将文件指针移动到文件首部,相当于fseek(fp,0,SEEK_END)
rewind(fp);//将文件指针移动到文件首部
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UFBrkQCL-1631712200566)(C:\Users\刘锦\AppData\Roaming\Typora\typora-user-images\image-20210823211829480.png)]
这样就可以将文件中的内容读出并且输出,但是后面有很多ffff,是因为程序中的换行,即我们从键盘中输入的回车实际上在存储在文件中时候会以换行和回车两个操作来共同完成,而读取时只读将二者合为换行
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nL2v8OqR-1631712200567)(C:\Users\刘锦\AppData\Roaming\Typora\typora-user-images\image-20210823212629530.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iVHrBifA-1631712200568)(C:\Users\刘锦\AppData\Roaming\Typora\typora-user-images\image-20210823213126600.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-R5sGvnw3-1631712200568)(C:\Users\刘锦\AppData\Roaming\Typora\typora-user-images\image-20210823213145893.png)]
文本文件既可以用文本方式读,也可以用二进制方式读,二进制方式读和文本方式读有区别,“r”读“\n”就只是’‘\n’’,而“rb”会读回车和换行。
9、无格式输入输出
记得getchar()是从标准输入设备读取一个字符写入标准输出设备,要注意刷新缓存
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SdleWKcy-1631712200569)(C:\Users\刘锦\AppData\Roaming\Typora\typora-user-images\image-20210823223535266.png)]
int main() { int a = 0; scanf_s("%d", &a);//输入1回车存放在缓冲区,a将1提取走剩下的\n留给了getchar() char b = getchar();//从标准输入设备读入一个字符,此时的b为10'\n' }
10、装逼专用sleep(20)在<windows.h>中
每次执行会睡眠20毫秒
11、feof(fp)
若到达文件末尾则为非零值,如未达到则为零
要用清空缓存
int main()
{
FILE* fp = NULL;
errno_t tag = fopen_s(&fp, "文件.cpp", "r");//千万别写成“w”
if (fp == NULL)
{
printf("file open error");
exit(EXIT_FAILURE);
}
fseek(fp, 0, SEEK_END);//使文件指针移动到末尾
int len = ftell(fp);
//SEEK_END;
//SEEK_SET;
//SEEK_CUR;
printf("%d", len);
char ch = '\0';
rewind(fp);//将文件指针移动到文件首部,相当于fseek(fp,0,SEEK_END)
while (!feof(fp))//feof(fp)判断指针是否到达文件末尾,若未到达则值为零,到达则为零
{
ch=fgetc(fp);//从文件中获得一个字符
Sleep(0);
printf("%c", ch);
}
fclose(fp);
fp = NULL;
}
11、主函数带参数
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HmEYqpjr-1631712200569)(C:\Users\刘锦\AppData\Roaming\Typora\typora-user-images\image-20210824144546658.png)]
R;
printf("%d", len);
char ch = ‘\0’;
rewind(fp);//将文件指针移动到文件首部,相当于fseek(fp,0,SEEK_END)
while (!feof(fp))//feof(fp)判断指针是否到达文件末尾,若未到达则值为零,到达则为零
{
ch=fgetc(fp);//从文件中获得一个字符
Sleep(0);
printf("%c", ch);
}
fclose(fp);
fp = NULL;
}
# 11、主函数带参数
[外链图片转存中...(img-HmEYqpjr-1631712200569)]