读写文件与printf、scanf关联
printf – 屏幕 – 标准输出
scanf – 键盘 – 标准输入
perror – 屏幕 – 标准错误
系统文件:(打开和关闭由系统自动执行)
标准输入 – stdin – 0 一旦关闭了,scanf就不可以使用
标准输出 – stdout – 1 一旦关闭了,printf就不可以使用
标准错误 – stderr – 2
应用程序启动时,自动被打开,程序执行结束时,自动被关闭。 ---- 隐式回收。
1s = 1000ms
1ms = 1000us
1us == 1000ns
文件指针和普通指针区别:
FILE *fp = NULL;
借助文件操作函数来改变 fp 为空、野指针的状况。 fopen(); --> 相当于 fp = malloc(); 不能使用fp++操作
操作文件, 使用文件读写函数来完成。 fputc、fgetc、fputs、fgets、fread、fwrite
文件分类:
设备文件:屏幕、键盘、磁盘、网卡、声卡、显卡、扬声器…
磁盘文件:
文本文件: ASCII
二进制文件: 0101 二进制编码
文件操作一般步骤:
- 打开文件 fopen() --》 FILE *fp;
- 读写文件 fputc、fgetc、fputs、fgets、fread、fwrite
- 关闭文件 fclose()
打开、关闭文件函数:
FILE * fopen(const char * filename, const char * mode);
参1:待打开文件的文件名(访问路径)
参2:文件打开权限:
“r”: 只读方式打开文件, 文件不存在,报错。存在,以只读方式打开。
“w”: 只写方式打开文件, 文件不存在,创建一个空文件。文件如果存在,清空并打开。
“w+”:读、写方式打开文件,文件不存在,创建一个空文件。文件如果存在,清空并打开。
“r+”:读、写方式打开文件, 文件不存在,报错。存在,以读写方式打开。
“a”: 以追加的方式打开文件。
“b”: 操作的文件是一个二进制文件(Windows)
返回值:成功:返回打开文件的文件指针
失败:NULL
int fclose(FILE * stream);
参1:打开文件的fp(fopen的返回值)
返回值:成功 :0, 失败: -1;
FILE* fp = NULL;
fp = fopen("C:\\Users\\胡永婷\\Desktop\\text1.txt","r"); // 不能用 C:\\Users\\胡永婷\\Desktop\\text.txt
if (fp = NULL)
{
perror("fopen error"); // 相当于printf("fopen error\n"),会返回错误号,而每个错误号对应一个函数 :xxxxx
getchar();
return -1;
}
fclose(fp);
文件访问路径:
绝对路径:
从系统磁盘的 根盘符开始,找到待访问的文件路径
Windows书写方法:
1)C:\Users\afei\Desktop\06-文件分类.avi
2)C:/Users/afei/Desktop/06-文件分类.avi — 也使用于Linux。
相对路径:(相对于当前的编译环境)
1)如果在VS环境下,编译执行(Ctrl+F5),文件相对路径是指相对于 day10.vcxproj 所在目录位置。
2)如果是双击 xxx.exe 文件执行,文件的相对路径是相对于 xxx.exe 所在目录位置。
1. 按字符写文件 fputc:
int fputc(int ch, FILE * stream);
参1:待写入的 字符
参2:打开文件的fp(fopen的返回值)
返回值: 成功: 写入文件中的字符对应的ASCII码
失败: -1
练习:写26个英文字符到文件中。
char* filename = "C:\\Users\\胡永婷\\Desktop\\text.txt";
FILE *fp = fopen(filename,"a+");
// 不能用 C:\\Users\\胡永婷\\Desktop\\text.txt
int ret = 0;
// 一定要检查返回值
if (fp == NULL)
{
perror("fopen error");
getchar();
return -1; // 打开出错返回-1
}
//char ch = 'a';
//while (ch < 'z')
//{
// ret = fputc(ch, fp);
// if (ret == -1)
// {
// perror("fputc error");
// return -1;
// }
// ch++;
//}
char *buf = "abcdefghijklmnopqrstuvwxy";
while (*buf)
{
ret = fputc(*buf, fp);
if (ret == -1)
{
perror("fputc error");
return -1;
}
buf++;
}
fclose(fp);
2.按字符读文件 fgetc
int fgetc(FILE * stream);
参1:待读取的文件fp(fopen的返回值)
返回值: 成功:读到的字符对应的ASCII码
失败: -1
文本文件的结束标记: EOF —》 -1 二进制文件不可以
3.feof()函数:
int feof(FILE * stream);
参1: fopen的返回值
返回值: 到达文件结尾–》非0【真】
没到达文件结尾–》0【假】
作用: 用来判断到达文件结尾。 既可以判断文本文件。也可以判断 二进制文件。
特性:要想使用feof()检测文件结束标记,必须在该函数调用之前,使用读文件函数。 比如:ch = fgetc(fp); feof()调用之前,必须有读文件函数调用。
void write_file()
{
FILE *fp = fopen("C:\\Users\\胡永婷\\Desktop\\text1.txt", "w"); // 这里一定要是”,不能是',否则会出错
if (fp == NULL)
{
perror("fopen error");
return; // 这里没有返回值,不能写-1
}
fputc('a', fp);
fputc('b', fp);
fputc(-1, fp);
fputc('d', fp);
fputc('\n', fp);
fclose(fp);
}
void read_file1()
{
FILE* fp = fopen("C:\\Users\\胡永婷\\Desktop\\text.txt", "r");
if (fp == NULL)
{
perror("fopen error");
return ;
}
char ch = fgetc(fp);
printf("ch = %c\n", ch); // 这里是双引号,不是单引号,只有python才可以双赢号单引号混用
ch = fgetc(fp);
printf("ch = %c\n", ch); // 这里是双引号,不是单引号,只有python才可以双赢号单引号混用
ch = fgetc(fp);
printf("ch = %c\n", ch); // 这里是双引号,不是单引号,只有python才可以双赢号单引号混用
fclose(fp);
}
void dynamic_read()
{
FILE* fp = fopen("C:\\Users\\胡永婷\\Desktop\\text1.txt", "r");
char ch= 0;
if (fp == NULL)
{
perror("fopen error");
return;
}
while (1)
{
ch = fgetc(fp);
if (ch == EOF)
{
break;
}
printf("ch = %c\n", ch); // 这里是双引号,不是单引号,只有python才可以双赢号单引号混用
}
}
void dynamic_read_fefo()
{
FILE* fp = fopen("C:\\Users\\胡永婷\\Desktop\\text1.txt", "r");
char ch = 0;
if (fp == NULL)
{
perror("fopen error");
return;
}
while (1)
{
ch = fgetc(fp); // 一次读一个字符,读到字符直接丢弃
if (feof(fp))
{
break;
}
printf("ch = %c\n", ch); // 这里是双引号,不是单引号,只有python才可以双赢号单引号混用
}
}
int main(void)
{
write_file();
read_file();
//dynamic_read(); // a,b
dynamic_read_fefo();
/*
ch = a
ch = b
ch =
ch = d
ch =
*/
}
4.fgets()函数:
获取一个字符串, 以\n作为结束标记。自动添加 \0. 空间足够大 读\n, 空间不足舍弃\n, 必须有\0。
char * fgets(char * str, int size, FILE * stream);
char buf[10]; hello --> hello\n\0
返回值: 成功: 读到的字符串
失败: NULL
char buf[10] = { 0 };
printf("%s\n", fgets(buf, 10, stdin)); // 输入 hello+enter ,相当于hello \n,所以在打印时会将\n也打印出来
/*
hello
hello
G:\VS\day03\x64\Release\day03.exe (进程 20892)已退出,代码为 0。
按任意键关闭此窗口. . .
*/
//printf("%s\n", fgets(buf, 5, stdin));
/*
hello
hell
请按任意键继续. . .
*/
5.fputs()函数:
写出一个字符串,如果字符串中没有\n, 不会写\n。
int fputs(const char * str, FILE * stream);
返回值: 成功: 0
失败: -1
char buf[10] = { 0 };
//char* str = "hello";
//fputs(str, stdout);
/*
hello
G:\VS\day03\x64\Release\day03.exe (进程 20436)已退出,代码为 0。
按任意键关闭此窗口. .
*/
char* str = "hello\n";
fputs(str, stdout);
/*
hello
G:\VS\day03\x64\Release\day03.exe (进程 18852)已退出,代码为 0。
按任意键关闭此窗口. . .
*/
【练习: 获取用户键盘输入,写入文件。】
假定:用户写入“:wq”终止接收用户输入,将之前的数据保存成一个文件。
FILE* fp = fopen("C:\\Users\\胡永婷\\Desktop\\text1.txt", "w");
if (fp == NULL)
{
perror("fopen error");
return -1;
}
char buf[4096]={0}; // 少于1kb都分配1KB大小,所以可以直接写4096
while (1)
{
fgets(buf, 4096, stdin);
if (strcmp(buf, ":wq\n") == 0)
{
break;
}
fputs(buf,fp);
}
fclose(fp);
【练习: 文件版四则运算】:在文件中存有计算式,要求用程序读出文件,并计算出结果,写入文件中
// 写一个存在四则运算的文档
void write_file()
{
FILE* fp = fopen("C:\\Users\\胡永婷\\Desktop\\text.txt", "w"); // ‘w'把原来写的覆盖掉
if (fp == 0)
{
perror("fopen error");
return;
}
fputs("10/2=\n",fp);
fputs("10*3=\n",fp);
fputs("10-2=\n",fp);
fputs("10+2=\n",fp);
fclose(fp);
}
// 读取文件
void read_file()
{
char buf[4096] = { 0 };
char result_buf[4096] = { 0 };
float a, b;
char ch;
float c;
char sum_result[4096] = { 0 };
FILE* fp = fopen("C:\\Users\\胡永婷\\Desktop\\text.txt", "r");
if (fp == 0)
{
perror("fopen error");
return;
}
while (1)
{
fgets(buf, 4096, fp); // gets函数固定从键盘上读 buf = "10/2=\n\0"
// 判断到文件结尾
if (feof(fp))
{
break;
}
sscanf(buf, "%f%c%f=\n", &a, &ch, &b); // a:10 ch:/ b:2
// 计算
switch (ch)
{
case '/':
c = a / b;
break;
case '*':
c = a * b;
break;
case '+':
c = a + b;
break;
case '-':
c = a - b;
break;
default:
break;
}
// 输出结果
sprintf(result_buf, "%f %c %f = %.2f\n", a, ch, b, c); // 写入才需要地址,读不需要地址
// 将输入的结果拼接起来
strcat(sum_result, result_buf);
}
/*printf(sum_result);*/
fclose(fp);
// 将只有表达式没有结果的文件关闭,再次打开文件
FILE* fp1 = fopen("C:\\Users\\胡永婷\\Desktop\\text.txt", "w"); // 清空文件,在一个函数中不能定义两个指针
if (fp1 == 0)
{
perror("fopen error");
return;
}
fputs(sum_result, fp1); // 将既有表达式又有结果的字符串写入文件中
fclose(fp1);
}
int main(void)
{
//write_file();
read_file();
}
6.输入输出
6.1【输出】printf — sprintf — fprintf: s代表字符串,f代表文件
变参函数:参数形参中 有“...”, 最后一个固参通常是格式描述串(包含格式匹配符), 函数的参数个数、类型、顺序由这个固参决定。
printf("hello");
printf("%s", "hello");
printf("ret = %d+%d\n", 10, 5);
printf("%d = %d%c%d\n", 10+5, 10, '+', 5); --> 屏幕
char buf[1024]; //缓冲区
sprintf(buf, "%d = %d%c%d\n", 10+5, 10, '+', 5); --> buf 中
FILE * fp = fopen();
fprintf(fp, "%d = %d%c%d\n", 10+5, 10, '+', 5); --> fp 对应的文件中
6.2【输入】scanf — sscanf — fscanf
scanf("%d", &m); 键盘 --> m
char str[] = "98";
sscanf(str, "%d", &m); str --> m
FILE * fp = fopen("r");
fscanf(fp, "%d", &m); fp指向的文件中 --> m
void print_file() // 写入文件中
{
FILE* fp = fopen("C:\\Users\\胡永婷\\Desktop\\text.txt", "w");
if (fp == 0)
{
perror("fopen error");
return -1;
}
fprintf(fp, "%d%c%d=%d\n", 10, '*', 7, 10 * 7);
fclose(fp);
}
void scan_file() // 读文件
{
int a, b, c;
char ch;
FILE* fp = fopen("C:\\Users\\胡永婷\\Desktop\\text.txt", "r");
if (fp == 0)
{
perror("fopen error");
return -1;
}
fscanf(fp,"%d%c%d=%d\n",&a,&ch,&b,&c);
printf("%d%c%d=%d\n", a, ch, b, c); // 打印
}
int main(void)
{
print_file();
scan_file();
}
6.3 fprintf()函数: 写
int fprintf(FILE * stream, const char * format, ...);
6.4 fscanf()函数: 读
int fscanf(FILE * stream, const char * format, …);
成功:正确匹配的个数。
失败: -1
1)边界溢出。 存储读取的数据空间。在使用之前清空。(比如文件有8,8,6三个字符,输出时,输出四次不报错,会显示8,8,6,6)
2)fscanf函数,每次在调用时都会判断下一次调用是否匹配参数2, 如果不匹配提前结束读文件。(feof(fp) 为真)。
fscanf(fp,"%d\n",&a);
if(feof(fp))
break;
printf("%d\n",a)
输出 8,8
读取第一个数8,判断下一次调用(8)满足“%d\n”,接着执行程序
读取第二个数8,判断下一次调用(6)满足“%d\n”,接着执行程序
读取第三个数6,判断下一次调用(\n)不满足“%d\n”,提前结束程序
void write_file()
{
FILE *fp = fopen("abc.c", "w");
if (!fp) // fp == NULL
{
perror("fopen error");
return -1;
}
fprintf(fp, "%d\n", 10);
fprintf(fp, "%d\n", 8);
fprintf(fp, "%d\n", 6);
fclose(fp);
}
void read_file()
{
int a;
FILE *fp = fopen("abc.c", "r");
if (!fp) // fp == NULL
{
perror("fopen error");
return -1;
}
fscanf(fp, "%d\n", &a);
printf("%d\n" , a);
fscanf(fp, "%d\n", &a);
printf("%d\n", a);
fscanf(fp, "%d\n", &a);
printf("%d\n", a);
a = 0;
fscanf(fp, "%d\n", &a);
printf("%d\n", a);
fclose(fp);
}
// fscanf 循环读文件
void read_file2()
{
int a;
FILE *fp = fopen("abc.c", "r");
if (!fp) // fp == NULL
{
perror("fopen error");
return -1;
}
while (1)
{
fscanf(fp, "%d\n", &a); // 读
printf("%d\n", a);
if (feof(fp)) // 真-- 文件结尾
break;
}
fclose(fp);
}
// fgets 循环读文件
void read_file3()
{
char buf[1024];
FILE *fp = fopen("abc.c", "r");
if (!fp) // fp == NULL
{
perror("fopen error");
return -1;
}
while (1)
{
memset(buf , 0, 1024);
fgets(buf, 1024, fp);// 读 \n
if (feof(fp)) // 真-- 文件结尾
break;
printf("%d\n", buf[0]);
}
fclose(fp);
}
int main0101(void)
{
//write_file();
read_file3();
system("pause");
return EXIT_SUCCESS;
}
int main(void)
{
FILE *fp = fopen("test0101.txt", "r");
if (!fp) // fp == NULL
{
perror("fopen error");
return -1;
}
int a;
char ch;
char str[10];
int ret = fscanf(fp, "%d %c %s", &a, &ch, str);
printf("ret = %d\n", ret);
fclose(fp);
system("pause");
return EXIT_SUCCESS;
}
【练习:文件版排序】生成随机数,写入文件。将文件内乱序随机数读出,排好序再写回文件。
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
void write_rand()
{
FILE *fp = fopen("test02.txt", "w");
if (!fp) // fp == NULL
{
perror("fopen error");
return -1;
}
srand(time(NULL)); // 随机数种子
for (size_t i = 0; i < 10; i++)
{
fprintf(fp, "%d\n", rand() % 100); // 将生成的随机数写入文件
}
fclose(fp);
}
void BubbleSort(int * src, int len)
{
for (int i = 0; i < len - 1; i++)
{
for (int j = 0; j < len - 1 - i; j++)
{
if (src[j] > src[j + 1])
{
int temp = src[j];
src[j] = src[j + 1];
src[j + 1] = temp;
}
}
}
}
void read_rand02()
{
int arr[10], i = 0;
FILE *fp = fopen("test02.txt", "r");
if (!fp) // fp == NULL
{
perror("fopen error");
return -1;
}
while (1)
{
fscanf(fp, "%d\n", &arr[i]);// 从文件中读取一个随机数,存入数组arr
i++;
if (feof(fp)) // 先存储,后判断,防止最后一个元素丢失
break;
}
BubbleSort(arr, sizeof(arr)/sizeof(arr[0])); // 对读取到的乱序数组排序
fclose(fp); // 关闭文件
fp = fopen("test02.txt", "w"); // 重新w方式打开文件, 清空原未排序文件。
if (!fp) // fp == NULL
{
perror("fopen error");
return -1;
}
for (size_t i = 0; i < 10; i++)
fprintf(fp, "%d\n", arr[i]); // 写排好序的数组到文件
fclose(fp);
}
int main0201(void)
{
write_rand();
getchar();
read_rand02();
system("pause");
return EXIT_SUCCESS;
}
7. 读写文件
默认处理文本文件。
fgetc — fputc
fgets — fputs
fprintf – fscanf
7.1 fwrite()函数: 既可处理以文本文件。也处理二进制文件。
写出数据到文件中。
stu_t stu[4] = { … };
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
参1:待写出的数据的地址
参2:待写出数据的大小
参3:写出的个数 – 参2 x 参3 = 写出数据的总大小。
参4:文件
返回值: 成功:永远是 参3 的值。 — 通常将参2 传 1. 将参3传实际写出字节数。
失败:0
7.2 fread()函数:
从文件fp中读出数据。
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
参1:读取到的数据存储的位置
参2:一次读取的字节数
参3:读取的次数 – 参2 x 参3 = 读出数据的总大小
参4:文件
返回值: 成功:参数3. — 通常将参2 传 1. 将参3传欲读出的字节数。
0:读失败 – 到达文件结尾 – feof(fp)为真。
【练习:大文件拷贝】
已知一个任意类型的文件,对该文件复制,产生一个相同的新文件。
1. 打开两个文件, 一个“r”, 另一“w”
2. 从r中 fread , fwrite到 w 文件中。
3. 判断到达文件结尾 终止。
4. 关闭。
注意: 在windows下,打开二进制文件(mp3、mp4、avi、jpg...)时需要使用“b”。如:“rb”、“wb”
fclose(wfp);
fclose(rfp);
}
int main0401(void)
{
myfile_cp();
printf("---------------------finish\n");
system("pause");
return EXIT_SUCCESS;
}
7.3 随机位置 读:
文件读写指针。在一个文件内只有一个。
fseek():
int fseek(FILE *stream, long offset, int whence);
参1:文件
参2:偏移量(矢量: + 向后, - 向前)
参3: SEEK_SET:文件开头位置
SEEK_CUR:当前位置
SEEK_END:文件结尾位置
返回值: 成功:0, 失败: -1
7.4 ftell():
获取文件读写指针位置。
long ftell(FILE *stream);
返回:从文件当前读写位置到起始位置的偏移量。
借助 ftell(fp) + fseek(fp, 0, SEEK_END); 来获取文件大小。
7.5 rewind():
回卷文件读写指针。 将读写指针移动到起始位置。
void rewind(FILE *stream);
ypedef struct student {
int age;
char name[10];
int num;
} stu_t;
int main0501(void)
{
stu_t stu[4] = {
18, "afei", 10,
20, "andy", 20,
30, "lily", 30,
16, "james", 40
};
stu_t s1;
FILE *fp = fopen("test05.txt", "wb+");
if (!fp) // fp == NULL
{
perror("fopen error");
return -1;
}
int ret = fwrite(&stu[0], 1, sizeof(stu), fp); // 以二进制形式写入,
printf("ret = %d\n", ret);
fseek(fp, sizeof(stu_t)*2, SEEK_SET); // 从文件起始位置,向后偏移一个stu结构体
ret = fread(&s1, 1, sizeof(s1), fp);
printf("ret = %d\n", ret);
printf("1 age= %d, name=%s, num=%d\n", s1.age, s1.name, s1.num);
int len = ftell(fp); // 获取文件当前读写指针位置,到文件起始位置的偏移量。
printf("len = %d\n", len);
rewind(fp); // 将文件读写指针回卷到起始。
ret = fread(&s1, 1, sizeof(s1), fp);
printf("2 age= %d, name=%s, num=%d\n", s1.age, s1.name, s1.num);
// 获取文件大小。
fseek(fp, 0, SEEK_END); // 将文件读写指针放到文件结尾。
len = ftell(fp);
printf("文件大小为:%d\n", len);
fclose(fp);
system("pause");
return EXIT_SUCCESS;
}
int main0502(void)
{
FILE *fp = fopen("test0501.txt", "w+"); // "r+"
int ret = fputs("11111", fp);
printf("ret 1 = %d\n", ret); // 0 表示成功。
ret = fputs("22222", fp);
printf("ret 2 = %d\n", ret);
ret = fputs("33333", fp);
printf("ret 3 = %d\n", ret);
char buf[1024] = { 0 };
//fseek(fp, 5 * 2, SEEK_SET); // 改变读写指针位置。
rewind(fp); // 起始位置。
char *ptr = fgets(buf, 1024, fp);
if (ptr == NULL)
printf("ptr == NULL \n");
printf("fgets ptr = %s\n", ptr);
printf("buf = %s\n", buf);
fclose(fp);
system("pause");
return EXIT_SUCCESS;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main0503(int argc, char *argv[])
{
FILE *fp = fopen("test1.txt", "r+");
char buf[6] = { 0 };
char *ptr = fgets(buf, 6, fp);
printf("buf=%s, ptr=%s\n", ptr, buf);
fseek(fp, 0, SEEK_CUR); // windows下需要添加这一句话
int ret = fputs("AAAAA", fp);
printf("ret = %d\n", ret);
fclose(fp);
system("pause");
return 0;
}
Linux和windows文件区别:
1)对于二进制文件操作, Windows 使用“b”, Linux下二进制和文本没区别。
2)windows下,回车 \r, 换行 \n。 \r\n , Linux下 回车换行\n
3) 对文件指针,先写后读。windows和Linux效果一致。
先读后写。Linux无需修改。windows下需要在写操作之前添加 fseek(fp, 0, SEEK_CUR); 来获取文件读写指针,使之生效。
获取文件状态:
打开文件,对于系统而言,系统资源消耗较大。
int stat(const char *path, struct stat *buf);
参1: 访问文件的路径
参2: 文件属性结构体
返回值: 成功: 0, 失败: -1;
/*
* 这种获取文件大小需要打开文件,很消耗内存
FILE *fp = fopen("test05.txt", "r");
fseek(fp, 0, SEEK_END);
int len = ftell(fp);
printf("文件大小:%d\n", len);
fclose(fp);
*/
int main0602(void)
{
struct stat buf;
int ret = stat("test05.txt", &buf); // 传出参数:在函数调用结束时,充当函数返回值。
printf("文件大小:%d\n", buf.st_size); // 不打开文件,获取文件大小。
system("pause");
return EXIT_SUCCESS;
}
删除、重命名文件:
int remove(const char *pathname); 删除文件。
int rename(const char *oldpath, const char *newpath); 重名文件
成功:0 ; 失败:-1
缓冲区刷新:
标准输出-- stdout – 标准输出缓冲区。 写给屏幕的数据,都是先存缓冲区中,由缓冲区一次性刷新到物理设备(屏幕)
标准输入 – stdin – 标准输入缓冲区。 从键盘读取的数据,直接读到 缓冲区中, 由缓冲区给程序提供数据。
预读入、缓输出。
行缓冲:printf(); 遇到\n就会将缓冲区中的数据刷新到物理设备上。
全缓冲:文件。 缓冲区存满, 数据刷新到物理设备上
无缓冲:perror。 缓冲区中只要有数据,就立即刷新到物理设备。
文件关闭时, 缓冲区会被自动刷新。 隐式回收:关闭文件、刷新缓冲区、释放malloc
手动刷新缓冲区: 实时刷新。
int fflush(FILE *stream);
成功:0
失败:-1
FILE *fp = fopen("test07.txt", "w+");
if (!fp)
{
perror("fopen error");
return -1;
}
char m = 0;
while (1)
{
scanf("%c", &m);
if (m == ':')
{
break;
}
fputc(m, fp);
fflush(fp); // 手动刷新文件缓冲到物理磁盘。
}
// 当文件关闭时,会自动刷新缓冲区。
fclose(fp);