【c++】文件

第1节  文件概述,文本、二进制文件区别

根据组织形式,人类把文件分为ASCII文件(文本文件)和二进制文件。

ASCII文件:每个字节存放一个ASCII码,表示一个字符,打开就能看懂里面的内容;

二进制文件:把内存中数据的存储形式原样输出到磁盘上存放。

【注】操作系统会根据文件的扩展名打开特定的编辑器,将其转换为人类能看懂的内容。

文件对于计算机来说都是二进制数据,但是人类可以选择通过文本方式写入还是二进制方式写入,打开也一样。

双击或者type、cat等方式就是通过文本方式打开文件,如果用代码或者加二进制标记打开文件,就是另一种。

人类所理解的二进制:

short int a = 10000;
int len = sizeof(a);
a = 10000;

在这里,观察内存可知0x009CF97C处存放的为10,0x009CF97D处存放的是27(两个十六进制数为8位二进制,代表一个字节,所以两个字节用来存放a,正好对应short int存储的a占两字节),因为计算机是小端存储,即高地址存放高位,低地址存放地位,所以存放的十六进制数实际为0x2710,即为十进制数的10000。

※ 10000存放的十六进制为31 30 30 30 30,计算机把10000看作五个字节,31对应十进制为49,对应ASCII码为‘1’。

 

第2节  文件的开、关、读、写

一、文件的打开

文件读写之前,必须要打开,读写之后,必须要关闭!

FILE *fp;
fp = fopen(文件名,使用文件的方式);    //这两个参数都是字符串
如:fp = fopen("a.txt","r");    //只读打开a.txt

通过fopen,告诉系统打开的文件名(当前目录)、打开方式、指向被打开文件的指针名。

文件有个位置指针fgetc,当用追加指针打开文件时,位置指针指向文件末尾。

二、文件的关闭

问题:为什么要关闭?

a)释放该文件占用的FILE结构的内存单元;

b)关闭文件的动作会触发系统把缓冲区中的数据写入磁盘,避免了缓冲区数据丢失。

if(fp){
    fclose(fp);    //返回值一般没有用,一般不会失败
}

三、文件的读写简单讲

fputc():把一个字符写到磁盘文件上去,如果失败(比如是只读打开文件的),返回EOF(End of File,系统定义成-1),若成功,返回写入的字符的ASCII值。

fputc(ch,fp);    //ch就是一个字符

fgetc():返回读入的字符,如果失败,返回EOF。

char reco = fgetc(fp);
//while (reco != EOF) {    //判断是否读完
while(!feof(fp)){    //这样写更规范
    putchar(reco);
    reco = fgetc(fp);
}

其他的一些关于文件的函数:

四、文件读写实战操作

 读取配置文件中的每一行元素并以字符串的形式展示出来!

FILE *fp = fopen("config.txt", "r");
if (!fp) {
    cout << "文件打开失败" << endl;
}else {
    char LineBuff[1024];
    while (!feof(fp)) {
        LineBuff[0] = 0;	//相当于清空,但是经过测试好像fgets函数自己有清空第一个参数的功能
        //读取一行,遇到0x0A结束,该函数把0x0D好像删除了,只剩下0x0A
        if (fgets(LineBuff, sizeof(LineBuff) - 1, fp)==NULL) {    //其实每次读的是第二个参数-1 
            //说明这行读的有问题            
            continue;   
        }
        if (LineBuff[0] == 0)
            continue;
        //若LineBuff中有东西,必须删除最后的换行符'\n'
    lblprocstring:
        if (strlen(LineBuff) > 0) {
            if (LineBuff[strlen(LineBuff) - 1] == 10 || LineBuff[strlen(LineBuff) - 1] == 13) {
                LineBuff[strlen(LineBuff) - 1] = 0;
                goto lblprocstring;
            }	
        }
        if (strlen(LineBuff) <= 0)
            continue;
        printf("%s\n", LineBuff);
    }    //end while
}
fclose(fp);    //end if(!fp) 

简单的文件读写代码(c++)

#include <iostream> 
#include <fstream>
#include <vector> 
#include <string>

using namespace std; 
 
int main() 
{
    //写入文件 
    string str;
    cin>>str;
    ofstream of;
    of.open("a.txt");
    of << str <<endl;
    of.close();

    //读出文件
    ifstream ii;
    ii.open("a.txt");
    string temp;
    vector<string> vec; 
    while(getline(ii,temp)){
        vec.push_back(temp);
    }
    for(auto iter=vec.begin();iter!=vec.end();iter++){
        cout << *iter <<endl;
    }
    ii.close();
    return 0;
}

 

第3节  将结构体写入二进制文件再读出

一、将结构体写入二进制文件

fwrite:用于向文件中写入数据。

fwrite(buffer,size,count,fp);

buffer:要写到文件中去的数据的地址的存放位置;

size:要写入文件的一个结构体的字节数

count:有几个size字节数

如果fwrite失败,返回0,成功则返回count。

struct stu {
    char name[20];
    int age;
    double score;
};
//main中
struct stu student[2];
strcpy(student[0].name, "张三abc");
student[0].age = 21;
student[0].score = 92.1f;
strcpy(student[1].name, "李四def");
student[1].age = 19;
student[1].score = 86.2f;

FILE *fp;
fp = fopen("structfile.bin", "wb");
if (!fp) {
    cout << "文件打开失败" << endl;
}
else {
    int result = fwrite(student, sizeof(struct stu), 2, fp);
    fclose(fp);
}

【注意事项】

a)往文件里写的结构体中不要出现指针

b)vs编译器往往会多加几个字节凑8字节对齐,linux gcc编译器会多几个字节凑4字节对齐

解决方法:强行1字节对齐(不用对齐),在定义结构体前加#pragma pack(1),定义结构体后加#pragma pack()!

二、从二进制文件中读出结构体

fread(buffer,size,count,fp);

示例:

FILE *fp;
fp = fopen("structfile.bin", "rb");
if (!fp) {
    cout << "文件打开失败" << endl;
}
else {
    struct stu structnew[2];
    int result = fread(structnew, sizeof(struct stu), 2, fp);
    fclose(fp);
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值