文件管理(IO流)(C语言与C++区别)

15 篇文章 1 订阅

文件管理(C语言):

一、 哪些可以放在头文件中,哪些不可以放在头文件中

1) 函数声明可以放在头文件中,函数定义(函数体)不可以放在头文件中

例如:Int Find();

2) 全局变量声明(extern)可以放在头文件中,函数定义(函数体)不可以放在头文件中

例如:extern struct SStud g_stud[100];

3) 常量声明(定义)可以放在头文件中

例如:#define COUNT sizeof(g_stud[100])/sizeof(g_stud[0])

4) 结构体声明(定义)可以放在头文件中

例如:

struct SStud
{
           IntnNumb;
           CharsName[20];
};

二、文件操作(C语言)

1) 文件的目的是保存进程中的数据,下次启动进程时还要使用

2) 学习操作,主要学习4大主要函数:

① 打开文件函数:fopen

② 关闭文件函数:fclose

③ 读文件函数:fwrite

④ 写文件函数:fwrite

⑤ 其他fputc,fputc,fprintf,rewind等等函数,头文件都是stdio.h

三、 fopen函数:建立一个FILE*指针,连接到文件上

函数原型:FILE * fopen(const char *path , const char *mode);

参数:filename:指定绝对路径或者相对路径的文件名

Mode:分别指定

“r”:当文件存在返回有效的文件指针,当文件不存在返回空指针

“w”:如果文件不存在,创建文件,如果文件存在,清空该文件并重写内容,失败的原因有:
①文件的路径有问题
②文件只读
③文件被占用
④windows磁盘安全限制写入

“a”:如果文件不存在,创建文件,如果文件存在,不清空原有内容,在原有内容后面

“w”和”a”都会返回空指针。

四、 fclose:断开FILE*文件指针和文件的链接

a)不能带入空指针

五、fwrite和fread函数

a)fwrite:调用fwrite必须是使用“w”或者“a”模式打开

memcpy是将一段缓冲区的内容复制到另外一段缓冲区上

fwrite是将一段缓冲区的内容复制到磁盘文件上

fread是将磁盘上的内容读取到一段缓冲区上

六、

扩展模式:

t:缺省时text模式,不推荐使用

b:二进制模式,推荐使用

其他读写模式:

“r+”:可读可写,主要特征和失败原因同r模式

“w+”:可读可写,主要特征和失败原因同w模式

“a+”:可读可写,主要特征和失败原因同a模式

七、其他的f族函数:

a)getc :getc等价于fread(&c,1,sizeof(char),fp)
b)putc(fputc):等价于fwrite(&c,1,sizeof(char),fp)
c) fputs:等价于fwrite(s,strlen(s),fp)
d) fgets: 用fwrite()不容易实现

八、文件寻址函数

a)ftell:告诉当前文件指针距离头部的位置(字节)
b)fseek:将文件指针放置到距离原点的某个距离上
如何查找一个文件是否存在?
fopen(…,”r”)返回值是NULL代表不存在

文件管理(C++):

一、 流是什么

“流”即是流动的意思,是物质从一处向另一处流动的过程,是对一种有序连续且具有方向性的数据( 其单位
可以是bit,byte,packet )的抽象描述
。 C++流是指信息从外部输入设备(如键盘)向计算机内部(如内存)
输入和从内存向外部输出设备(显示器)输出的过程。这种输入输出的过程被形象的比喻为“流”。
它的特性是:有序连续、具有方向性
为了实现这种流动,C++定义了I/O标准类库,这些每个类都称为流/流类,用以完成某方面的功能

二. C++IO流

C++系统实现了一个庞大的类库,其中ios为基类,其他类都是直接或间接派生自ios类
在这里插入图片描述## 三、C++标准IO流
C++标准库提供了4个全局流对象cin、cout、cerr、clog,使用cout进行标准输出,即数据从内存流向控制
台(显示器)。
使用cin进行标准输入即数据通过键盘输入到程序中,同时C++标准库还提供了cerr用来进行标
准错误的输出,以及clog进行日志的输出
,从上图可以看出,cout、cerr、clog是ostream类的三个不同的
对象,因此这三个对象现在基本没有区别,只是应用场景不同。
在使用时候必须要包含文件并引入std标准命名空间。
注意:
**1. cin为缓冲流。键盘输入的数据保存在缓冲区中,当要提取时,是从缓冲区中拿。如果一次输入过多,会留在那儿慢慢用,如果输入错了,必须在回车之前修改,如果回车键按下就无法挽回了。只有把输入缓冲区中的数据取完后,才要求输入新的数据。

  • 输入的数据类型必须与要提取的数据类型一致,否则出错。出错只是在流的状态字state中对应位置位(置1),程序继续。
  • 空格和回车都可以作为数据之间的分格符,所以多个数据可以在一行输入,也可以分行输入。但如果是字符型和字符串,则空格(ASCII码为32)无法用cin输入,字符串中也不能有空格。回车符也无法读入。
  • cin和cout可以直接输入和输出内置类型数据,原因:标准库已经将所有内置类型的输入和输出全部重载了**
    5. 对于自定义类型,如果要支持cin和cout的标准输入输出,需要对<<和>>进行重载。

四、C++文件IO流

C++根据文件内容的数据格式分为二进制文件和文本文件。采用文件流对象操作文件的一般步骤:
1. 定义一个文件流对象

  • ifstream ifile(只输入用)
  • ofstream ofile(只输出用)
  • fstream iofile(既输入又输出用)

2、使用文件流对象的成员函数打开一个磁盘文件,使得文件流对象和磁盘文件之间建立联系
3、使用提取和插入运算符对文件进行读写操作,或使用成员函数进行读写
4、关闭文件

// IO流
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>

using namespace std;


//使用文件IO流用二进制方式演示读写配置文件
struct ServerInfo
{
    char _ip[32];   //ip
    int _port;      //端口
};

struct ConfigManager
{
public:
    explicit ConfigManager(const char *configfile = "bitsrver.config")
            : _configfile(configfile)
    {
    }

    void WriteBin(const ServerInfo &info)
    {
        //使用二进制方式打开写
        ofstream ofs(_configfile, ofstream::in | ofstream::binary);
        ofs.write((const char *) &info, sizeof(ServerInfo));
        ofs.close();
    }

    void ReadBin(ServerInfo &info)
    {
        //使用二进制方式打开读
        ifstream ifs(_configfile, ifstream::out | ifstream::binary);
        ifs.read((char *) &info, sizeof(ServerInfo));
        ifs.close();
    }

    void WriteText(const ServerInfo &info)
    {
        //C++用IO流写整型比C语言简单
        ofstream ofs(_configfile);
        ofs << info._ip << endl;
        ofs << info._port << endl;
        ofs.close();
    }

    void ReadText(ServerInfo &info)
    {
        ifstream ifs(_configfile);
        ifs >> info._ip;
        ifs >> info._port;
        ifs.close();
    }


private:
    string _configfile; //配置文件
};

int main1()
{
    ConfigManager cfgMgr;

    ServerInfo wtinfo;
    ServerInfo rdinfo;
    strcpy(wtinfo._ip, "127.0.0.1");
    wtinfo._port = 80;

    //二进制读写
    cfgMgr.WriteBin(wtinfo);
    cfgMgr.ReadBin(rdinfo);
    cout << rdinfo._ip << endl;
    cout << rdinfo._port << endl;

    //文本读写
    cfgMgr.WriteText(wtinfo);
    cfgMgr.ReadText(rdinfo);
    cout << rdinfo._ip << endl;
    cout << rdinfo._port << endl;
    return 0;
}

//转换为字符串
int main()
{
    int a = 1234567;

    stringstream ss;
    ss << a;

    string str = "";
    ss >> str;

    cout << a << endl;
    cout << str << endl;

    //在进行下一次转换之前需要进行清空,否则会转换失败
    //只是清空状态,不会清空内部管理的string对象
    //string对象会累加
    ss.clear();
    double d = 3.14;
    ss << d;
    ss >> str;
    cout << d << endl;
    cout << str << endl;
    cout << ss.str() << endl;
    return EXIT_SUCCESS;
}

五、stringstream的简单介绍

在C语言中,如果想要将一个整形变量的数据转化为字符串格式,如何去做?
1. 使用itoa()函数
2. 使用sprintf()函数
但是两个函数在转化时,都得需要先给出保存结果的空间,那空间要给多大呢,就不太好界定,而且转化格
式不匹配时,可能还会得到错误的结果甚至程序崩溃
注意:
1. stringstream实际是在其底层维护了一个string类型的对象用来保存结果。
2. 多次数据类型转化时,一定要用clear()来清空,才能正确转化,但clear()不会将stringstream底层的string对象清空。
3. 可以使用s. str("")方法将底层string对象设置为""空字符串。
4. 可以使用s.str()将让stringstream返回其底层的string对象。
5. stringstream使用string类对象代替字符数组,可以避免缓冲区溢出的危险,而且其会对参数类型进行推演,不需要格式化控制,也不会出现格式化失败的风险,因此使用更方便,更安全。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

枳洛淮南✘

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值