C语言中的文件操作函数

平时用Qt的QFile用的习惯了,发现其实连C语言的文件操作函数都不熟悉,专门用C++写了个通讯录的命令行程序练手,总结一下用到的几个函数,使用这几个函数需要#include <stdio.h>

fopen和fclose函数

系统需要在内存中为每个读写的文件开辟一段缓存,缓存中保存文件信息的是FILE结构体,打开文件时就会获得指向FILE的指针。为什么要用缓存呢,因为硬盘读取时很慢的,机械硬盘的读写时间都是毫秒级,而内存读写是纳秒级的,差了一百万倍。

函数原型为fopen(const char* filePath, const char* mode)fclose(FILE* file)。文件打开成功后,会返回指向流的文件指针,如果打开失败则返回NULL,最后一定要用fclose关闭文件。一般是这样使用:

FILE* file = fopen("file.dat","r");
if(file==NULL)
    std::cout<<"读取文件失败!"<<endl;

    ......

fclose(file);

常用的mode有以下几种:

r是只读模式,文件必须存在
r+是可读写模式,文件必须存在
w是只写模式,文件若存在则清空重新写,若不存在则创建文件再写。
w+是可读写模式,文件若存在则清空重新写,若不存在则创建文件再写。

a是以附加方式打开只写文件,若文件不存在则创建文件,若存在则数据添加到文件尾部,原内容保留。
wb是用只写方式打开一个二进制文件,只允许写数据
wt是用只写方式打开一个文本文件,只允许写数据

还可以进行组合模式,例如at+,ab+,wb+等等。

fread函数

用于读取文件流,原型为size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);

buffer   是读取的数据存放的内存的指针(可以是数组,也可以是新开辟的空间,buffer就是一个索引)   
size       是每次读取的字节数  
count     是读取次数  
strean   是要读取的文件的指针   

一般这样使用,在fopen打开文件后,读取文件:

    FILE* fr = fopen("F:/list.dat","r");
    char buff[50];  //定义缓冲区
    while(!feof(file))
    {
        memset(buff,0,sizeof(buff));    // 清空缓冲区 
        fread(buff,sizeof(char),sizeof(buff),file);   //单字节读取
        cout<<buff;
    }
    fclose(fr);

feof函数的原型:int feof(FILE * stream);,用来检测文件流的位置,判断是否读到了文件结尾。检测到文件结束标识返回1,否则返回0。

feof()与EOF不同:feof()是函数,用来检测文件的结束;EOF是 End Of File 的缩写,是C语言中标准库中定义的宏,定义为:#define EOF (-1)

程序连续读取file中的50个字符,文件指针会跟着移动,最终会根据文件结束符而停止。目前的问题是 读文件时总是出现大量乱码 ,只有读取用fwrite写的文件才正常。

fwrite函数

函数原型为size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
一般这样使用:

FILE* fa = fopen("F:/list.dat","a+");   //追加式写入
const char* j = "hello world";
fwrite(j,5,1,fa);

向文件追加写入字符串,但只写入前五个,也就是hello

fseek函数

函数原型:int fseek(FILE *stream, long offset, int fromwhere);,用于重定位流数据流的内部指针。

stream:指向打开的文件指针。
offset:以基准点为起始点的偏移量。
fromwhere:基准点,包括`SEEK_SET 文件头`,`SEEK_CUR 当前位置`,`SEEK_END 文件件尾`。

成功,返回0;失败返回-1

常见用法:

fseek(fp, 100L, SEEK_SET);把stream指针移动到离文件开头100字节处;

fseek(fp, 100L, SEEK_CUR);把stream指针移动到离文件当前位置字节处;

fseek(fp, -100L, SEEK_END);把stream指针移动到离文件尾100字节处;

fgets函数

函数原型char* fgets(char * s, int n,FILE *stream);

s: 字符型指针,指向存储读入数据的缓冲区的地址
n: 从流中读入n-1个字符
stream:指向读取的流

如果读入成功,则返回缓冲区的地址;如果读入错误或遇到文件结尾(EOF),则返回NULL。用fgets读入数据时,先定义一个字符数组或字符指针。一般是这样使用:

FILE* fr = fopen("b.cpp","r");
char s[50];
while(fgets(s,50,fr)!=NULL)
{
    cout<<s;
}

第二个参数可以用较小的值,例如文本内容是1234567890时,如果第二个参数>=11,只需要读一次,否则需要读多次。fgets若没遇到换行符,会接着从前一次的位置继续读入n-1个字符,只要是文本流没关闭。

这个函数用于 读汉字文本时会出现乱码 ,读英文正常。

补充内容

Linux下没有itoa函数,只有atoi,因为itoa不是C标准库函数,而是扩展的非标准函数,因编译器而不同,gcc编译器不支持这个函数。

可以用这样的替代方法:

    int num = 1234567890;
    char s[11];
    sprintf(s,"%d",num);
    cout<<"conversion:"<<s<<endl;

猜你喜欢

转载自blog.csdn.net/yao5hed/article/details/81050488