C语言 09.文件

读写文件与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 二进制编码

文件操作一般步骤:

  1. 打开文件 fopen() --》 FILE *fp;
  2. 读写文件 fputc、fgetc、fputs、fgets、fread、fwrite
  3. 关闭文件 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);
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值