C/C++文件操作 超全的解释 还有代码演示

1.打开和关闭

int main() {
	char path[] = "Hole.txt";  //这里使用的是相对路径。
	FILE* file = fopen(path, "a+");
	/*
    "r" 打开一个用于读取的文本文件。文件必须存在。不存在则出错。
    "w" 打开一个用于写入的文本文件。若文件存在则文件长度清为0,即文件内容会消失。若文件不存在则建立该文件。 
    "a" 附加到一个文本文件。若文件存在,写入的数据会被加到文件尾,即文件原先的内容会被保留。若文件不存在,则会建立该文件。
    "rb" 打开一个用于读取的二进制文件。
    "wb" 打开一个用于写入的二进制文件。
    "ab" 附加到一个二进制文件。
    "r+" 打开一个用于读/写的文本文件。若文件不存在则出错。
    "w+" 打开一个用于读/写的文本文件。
    "a+" 附加到一个用于读/写的文本文件。
    "rb+" 打开一个用于读/写的二进制文件。
    "wb+" 打开一个用于读/写的二进制文件。
    "ab+" 附加到一个用于读/写的二进制文件。
	返回值:正常返回:FILE* 一个指向文件在内存中的文件信息块的指针。
            异常返回:NULL,表示打开操作不成功。
    */
    /*
    要说明的是:C语言将计算机的输入输出设备都看作是文件。
    例如,键盘文件、屏幕文件等。
    ANSI C标准规定,在执行程序时系统先自动打开键盘、屏幕、错误三个文件。
    这三个文件的文件指针分别是:标准输入stdin、标准输出stdout和标准出错stderr。
    */
    std::cout << file << std::endl;
    int ch = fgetc(file);  //从fp所指文件的当前指针位置读取一个字符 
    while(ch != EOF)
    {
        putchar(ch); //若不是结束符,将它输出到屏幕上显示
        std::cout << "  ";
        std::cout << ch << std::endl;
        ch = fgetc(file);  //从fp所指文件的当前指针位置读取一个字符 
    }
    int i = fputc('a', file);   //向文件中写入一个字符。第一个参数是待写入的字符,第二个参数是字符写入的文件(指向字符写入的文件的指针。)
    std::cout << i << std::endl;
    int ret = fclose(file);   //这个函数的参数就是指向打开文件的指针。
    //一定要记住在打开一个文件之后,操作完之后关闭它。
    /*正常返回:0
      异常返回:EOF,表示文件在关闭时发生错误
	*/
    std::cout << ret << std::endl;
    return 0;
}

请看,file的值是地址。
在这里插入图片描述
上面的代码里面还有fgetc()函数和fputc()函数,他们的作用分别是取文件里面的字符和向文件里面写入字符。
但是我在调试的时候发现了一个问题,那就是上面的操作是将打开文件里面的字符全都读取出来之后,再在文件尾写入一个字符,这样可以正常写入,但是如果只是读了一个字符的话,再用fputc()函数写入一个字符就写不进去,但是问题是函数正确的执行了,返回值也是正确的,但是文件里面却没有刚写入的字符。很是奇怪!

经过在CSDN发问答帖,得到大佬指点,加一个函数就可以解决了。

 fseek(file, 0L, SEEK_END);  //把文件指针定位到末尾
 //文件指针定位到文件末尾,偏移0个字节
int main() {
	char path[] = "Hole.txt";  //这里使用的是相对路径。
	FILE* file = fopen(path, "a+");
    std::cout << file << std::endl;
    int ch = fgetc(file);  //从fp所指文件的当前指针位置读取一个字符 
    if (ch != EOF) {
        putchar(ch);
        std::cout << std::endl;
    }
    fseek(file, 0L, SEEK_END);  //把文件指针定位到末尾
    //文件指针定位到文件末尾,偏移0个字节
    int i = fputc('a', file);   //向文件中写入一个字符。第一个参数是待写入的字符,第二个参数是字符写入的文件(指向字符写入的文件的指针。)
    std::cout << i << std::endl;
    int ret = fclose(file);   //这个函数的参数就是指向打开文件的指针。
    std::cout << ret << std::endl;
    return 0;
}

这样就可以在读了一个字符之后,然后通过fseek()函数把文件指针定位到末尾,这样就可以在末尾加入字符了。

2.写入、读出字符

fgetc()函数和fputc()函数上面的那个小节已经介绍并使用了。

fseek()函数

void rewind(FILE *fp);  //用来将文件指针移动到文件头。
int fseek(FILE *fp, long offset, int fromwhere);
//offset是偏移量,fromwhere的取值有三个。
//SEEK_SET	0	表示文件开头
//SEEK_CUR	1	表示文件当前位置
//SEEK_END	2	表示文件末尾

例如:
范例一:fseek(fp,0L,SEEK_END);
解释:文件指针定位到文件末尾,偏移0个字节。
范例二:fseek(fp,50L,0)或fseek(fp,50L,SEEK_SET);
解释:其作用是将位置指针移到离文件头50个字节处。

offset是long型数据,它表示位置指针相对于fromwhere移动的字节数。
如果位移量是一个正数,表示从fromwhere开始往文件尾方向移动;如果位移量是一个负数,则表示从fromwhere开始往文件头方向移动。

关于这个函数,我参考的这篇博客。

3.从文件中读取字符串,向文件中写入字符串

使用fgets()函数从文件中读取字符串,使用fputs()函数向文件中写入字符串。

fgets()函数使用说明:
由fp指出的文件中读取n-1个字符,并把他们存放到str指向的字符数组中,最后加上一个字符串结束符'\0'char *fgets(char *str, int n, FILE *fp)
参数说明:
    str:接受字符串的内存地址,可以是数组别名,也可以是指针
    n:指出要读取的字符的个数
    fp:这个是文件指针,指出要从中读取字符的文件
返回值:
    正常返回:字符串的内存首地址,即str的值
    异常返回:返回一个NULL值,此时应当用feof()ferror()函数来判别是读取到了文件尾,还是发生了错误。
int main() {
	char path[] = "Hole.txt";  //这里使用的是相对路径。
	FILE* file = fopen(path, "ab+");
    char path1[] = "Hole1.txt"; 
    FILE* file1 = fopen(path1, "ab+");
    const int SIZE = 7;
    char buffer[SIZE];
    while (fgets(buffer, SIZE, file) != NULL) {
        fputs(buffer,file1);
    }
    int ret = fclose(file);   //这个函数的参数就是指向打开文件的指针。
    fclose(file1);
    return 0;
}

这个函数实现的是将Hole.txt的文件里的字符串读出,把它们写入Hole1.txt中。
在这里插入图片描述

4.往文件中写格式化数据,格式化读取文件中的数据

int fprintf(FILE *fp,const char *format,arg_list)

将变量表列(arg_list)中的数据,按照format指出的格式,写入由fp指定的文件。fprintf()函数与printf()函数的功能相同,只是printf()函数是将数据写入屏幕文件(stdout)。
  fp:这是个文件指针,指出要将数据写入的文件。
  format:这是个指向字符串的字符指针,字符串中含有要写出数据的格式,所以该字符串成为格式串。格式串描述的规则与printf()函数中的格式串相同。
arg_list:是要写入文件的变量表列,各变量之间用逗号分隔。

int fscanf(FILE *fp, const char *format, agars)

fscanf():从文件指针fp指向的文件中,按format中对应的控制格式读取数据,并存储在agars对应的变量中。
一个完美的演示的例子。

#include <stdio.h>   
void main() {
    char name[10];
    int nAge, nClass;
    long number;
    FILE* fp;
    if ((fp = fopen("student.txt", "w")) == NULL)
    {
        printf("The file %s can not be opened.\n", "student.txt");
        return;
    }
    fscanf(stdin, "%s %d %d %ld", name, &nClass, &nAge, &number);
    fprintf(fp, "%s %5d %4d %8ld", name, nClass, nAge, number);
    fclose(fp);
    if ((fp = fopen("student.txt", "r")) == NULL)
    {
        printf("The file %s can not be opened.\n", "student.txt");
        return;
    }
    fscanf(fp, "%s %d %d %ld", name, &nClass, &nAge, &number);
    printf("name nClass nAge number\n");
    fprintf(stdout, "%-10s%-8d%-6d%-8ld\n", name, nClass, nAge, number);
    fclose(fp);
}

5.以二进制形式读取文件中的数据、以二进制形式写数据到文件中去

int fread(void *buffer,unsigned size,unsigned count,FILE *fp)

从由fp指定的文件中,按二进制形式将size*count个数据读到由buffer指出的数据区中。
buffer:这是一个void型指针,指出要将读入数据存放在其中的存储区首地址。
size:指出一个数据块的字节数,即一个数据块的大小尺寸。
count:指出一次读入多少个数据块。
fp:这是个文件指针,指出要从其中读出数据的文件。
正常返回:实际读取数据块的个数,即count。
异常返回:如果文件中剩下的数据块个数少于参数中count指出的个数,或者发生了错误,返回0值。此时可以用feof()和ferror()来判定到底出现了什么情况。

int fwrite(void *buffer,unsigned size,unsigned count,FILE *fp)

按二进制形式,将由buffer指定的数据缓冲区内的size*count个数据写入由fp指定的文件中去。
buffer:这是一个void型指针,指出要将其中数据输出到文件的缓冲区首地址。
size:指出一个数据块的字节数,即一个数据块的大小尺寸。
count:一次输出多少个数据块。
fp:这是个文件指针,指出要从其中读出数据的文件。
正常返回:实际输出数据块的个数,即count。
异常返回:返回0值,表示输出结束或发生了错误。

6.以二进制形式读取一个整数、以二进制形式存储一个整数

int getw(FILE *fp)

从由fp指定的文件中,以二进制形式读取一个整数。
fp:是文件指针。
正常返回:所读取整数的值。
异常返回:返回EOF,即-1。由于读取的整数值有可能是-1,所以必须用feof()或ferror()来判断是到了文件结束,还是出现了一个出错。

int putw(int n,FILE *fp)

以二进制形式把由变量n指出的整数值存放到由fp指定的文件中。
n:要存入文件的整数。
fp:是文件指针。
正常返回:所输出的整数值。
异常返回:返回EOF,即-1。由于输出的整数值有可能是-1,所以必须用feof()或ferror()来判断是到了文件结束,还是出现了一个出错。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章