真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

C++【IO流】-創(chuàng)新互聯(lián)

文章目錄
  • 一、C語言的輸入和輸出
  • 二、C++中的IO流
    • 自動類型識別
    • scanf和cin等輸入,都是通過空格或者換行分隔開來的
    • 多行測試用例如何寫輸入
  • 三、文件流
    • ifstream讀取文件
      • 讀取文件中不同類型的數(shù)據(jù)
    • 二進制讀寫和文本讀寫
    • 二進制文件的寫出
    • 二進制文件的讀取
      • 二進制讀寫的坑
    • 文本的方式寫和讀取
    • 文件流寫和讀(c++)
  • 四、istringstream
    • 序列化和反序列化
    • ostringstream和istringstream
    • stringstream

杜爾伯特網(wǎng)站制作公司哪家好,找成都創(chuàng)新互聯(lián)公司!從網(wǎng)頁設(shè)計、網(wǎng)站建設(shè)、微信開發(fā)、APP開發(fā)、響應(yīng)式網(wǎng)站等網(wǎng)站項目制作,到程序開發(fā),運營維護。成都創(chuàng)新互聯(lián)公司于2013年成立到現(xiàn)在10年的時間,我們擁有了豐富的建站經(jīng)驗和運維經(jīng)驗,來保證我們的工作的順利進行。專注于網(wǎng)站建設(shè)就選成都創(chuàng)新互聯(lián)公司。
一、C語言的輸入和輸出

C語言中我們用到的最頻繁的輸入輸出方式就是scanf ()與printf()。 scanf(): 從標準輸入設(shè)備(鍵盤)讀取數(shù)據(jù),并將值存放在變量中。printf(): 將指定的文字/字符串輸出到標準輸出設(shè)備(屏幕)。
注意寬度輸出和精度輸出控制。C語言借助了相應(yīng)的緩沖區(qū)來進行輸入與輸出。如下圖所示:
在這里插入圖片描述
這里的設(shè)備除了終端或者是控制臺之外,還可能是磁盤文件,或者是網(wǎng)卡。

對輸入輸出緩沖區(qū)的理解:
1.可以屏蔽掉低級I/O的實現(xiàn),低級I/O的實現(xiàn)依賴操作系統(tǒng)本身內(nèi)核的實現(xiàn),所以如果能夠屏
蔽這部分的差異,可以很容易寫出可移植的程序。
2.可以使用這部分的內(nèi)容實現(xiàn)“行”讀取的行為,對于計算機而言是沒有“行”這個概念,有了這部分,就可以定義“行”的概念,然后解析緩沖區(qū)的內(nèi)容,返回一個“行”。

printf/scanf
fprintf/fscanf
sprintf/sscanf

int main()
{int a=0;
    printf("%d",a);
    scanf("%d",&a);
    printf("%d\n",a);
    
}
二、C++中的IO流

在這里插入圖片描述
istream:流提取
ostream:流輸出
因為提取和輸出都要寫一個類,非常麻煩,就寫了一個特iostream,繼承了這兩個類的功能
(但是因為這里存在菱形繼承,所以非常復(fù)雜)

自動類型識別
int main()
{int i=0;
    double j=2.2;
    cout<

在這里插入圖片描述
這是因為庫底層都對其進行了函數(shù)的重載。

istream和ostream可以更好地支撐自定義類型對象的流插入和流提取。
自定義類型可以自己重載,控制流提取和流插入的方式。
(string,日期類都可以進行流插入和流提取的重載)

scanf和cin等輸入,都是通過空格或者換行分隔開來的
#includeint main()
{int year ,month ,day;
    //輸入多個值默認輸入是用空格或者換行分隔開來的。
    cin>>year>>month>>day;
    scanf("%d%d%d",&year,&month,&day);
    scanf("%d %d %d",&year,&month,&day);//不需要去加空格
    //如果日期是20221128這樣輸入的
    //我們可以用這種方式將我們的日期進行分隔
    scanf("%4d%2d%2d",&year,&month,&day);
    cout<>str;
    year=stoi(str.substr(0,4));
    month=stoi(str.substr(4,2));
    day=stoi(str.substr(6,2));
    cout<
多行測試用例如何寫輸入
int main()
{int year ,month ,day;
    string str;
    //使用了operate bool
    //怎么終止?ctrl+c直接kill -9終止進程。
    //ctr+z給一個流結(jié)束的標志。
    while(cin>>str)
    {year=stoi(str.substr(0,4));
        month=stoi(str.substr(4,2));
        day=stoi(str.substr(6,2));
        cout<

返回值是cin類型的對象。
一般是整型指針,比較運算符表達式道德結(jié)果可以做邏輯條件判斷,0就是假,非0就是真,自定義類型一般是不能做while的條件類型判斷的,這里存在隱式類型轉(zhuǎn)換
想要讓自定義類型能夠進行轉(zhuǎn)換,我們需要將其進行強制類型轉(zhuǎn)換,但是一般用于類型轉(zhuǎn)換的()被占用了,所以我們就用operator bool,將我們的類型轉(zhuǎn)化成一個bool值,并將這個bool值進行返回。
在這里插入圖片描述
這就類似于我們下面的將我們的自定義類型a賦值給內(nèi)置類型int的過程。

class A
{public:
    A(int a)
        :_a(a)
    {}
private:
    int _a;
};

int main()
{//內(nèi)置類型轉(zhuǎn)換成自定義類型
    //隱式類型轉(zhuǎn)換
    A aa1=1;//用1構(gòu)造A的臨時對象,再拷貝構(gòu)造aa1,優(yōu)化后直接構(gòu)造aa1
}

如何讓我們的自定義類型轉(zhuǎn)換成內(nèi)置類型

class A
{public:
    A(int a)
            :_a(a)
    {}
	
	//重載運算符
    operator int()
    {return _a;
    }
private:
    int _a;
};

int main()
{//自定義類型轉(zhuǎn)換成內(nèi)置類型1
    int i=aa1;
    cout<
三、文件流 ifstream讀取文件

在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述

int main()
{ifstream  ifs("/Users/Test.cpp");
    //讀取一個字符
    char ch=ifs.get();
    while(ifs)
    {cout<

在這里插入圖片描述

讀取文件中不同類型的數(shù)據(jù)

這是我們test.txt中的內(nèi)容
在這里插入圖片描述

可以更好地兼容自定義類型的讀寫

class Date
{friend ostream& operator<< (ostream& out, const Date& d);
    friend istream& operator >>(istream& in, Date& d);
public:
    Date(int year = 1, int month = 1, int day = 1)
            :_year(year)
            , _month(month)
            , _day(day)
    {}
    operator bool()
    {// 這里是隨意寫的,假設(shè)輸入_year為0,則結(jié)束
        if (_year == 0)
            return false;
        else
            return true;
    }
private:
    int _year;
    int _month;
    int _day;
};
istream& operator >>(istream& in, Date& d)
{in >>d._year >>d._month >>d._day;
    return in;
}
ostream& operator<< (ostream& out, const Date& d)
{out<< d._year<< " "<< d._month<<" "<< d._day ;
    return out;
}
int main()
{ifstream  ifs("/Users/test.txt");
    //可以使用c語言的方式從文件中讀取不同類型的數(shù)據(jù)
//    fscanf("%d%s%f",)
    //在c++中使用ifstream會方便一些
    int i;
    string s;
    double d;
    //對于自定義類型也是可以的
    //當(dāng)然,可以的前提是日期類對象重載了流提取
    Date de;
    //流提取
    ifs>>i>>s>>d>>de;
    cout<

在這里插入圖片描述

二進制讀寫和文本讀寫

二進制讀寫:就是文件在內(nèi)存中是如何存儲的,就怎樣寫到磁盤文件中
文本讀寫:序列化(json,xml),將對象數(shù)據(jù)按照某種格式進行轉(zhuǎn)換,序列化成字符串,寫入磁盤當(dāng)中。讀取回來的也是字符串,反序列化,再轉(zhuǎn)換成對象數(shù)據(jù)。

二進制讀寫:
優(yōu)點:快
缺點:寫出去的內(nèi)容看不見
(打開就大概率是亂碼了,比方說存了一個100,但是二進制讀寫出來是100的補碼)
文本讀寫:
優(yōu)點:可以看見寫出去的是什么
缺點:存在一個轉(zhuǎn)換的過程,要慢一些

二進制文件的寫出
#include#includeusing namespace std;
struct ServerInfo
{char _address[32];
    int _port;
};

struct ConfigureManager
{public:
    ConfigureManager(const char* filename="./server.config")
        :_filename(filename)
    {}

    void WriteBin (const ServerInfo& info)
    {//默認的寫都是覆蓋的模式進行寫入
        //但是app就是追加寫,也就是append
        ofstream ofs(_filename,ios_base::out|ios_base::binary);
        //需要傳入一個char*的字符串,然后第二個參數(shù)是要讀取的數(shù)據(jù)的大小
        ofs.write((char*)&info,sizeof(info));
    }
private:
    string _filename;

};
int main()

{ServerInfo info={"127.0.0.1",888};
    ConfigureManager cm;
    cm.WriteBin(info);
    return 0;
}

在這里插入圖片描述
這里我們的文本是不支持直接查看二進制文件的,所以我們這里的除了數(shù)字,別的我們文本的編碼都是不可見的。

二進制文件的讀取
#include#includeusing namespace std;
struct ServerInfo
{char _address[32];
    int _port;
};

struct ConfigureManager
{public:
    ConfigureManager(const char* filename="./server.config")
        :_filename(filename)
    {}


    void ReadBin (const ServerInfo& info)
    {//默認的寫都是覆蓋的模式進行寫入
        //但是app就是追加寫,也就是append
        ifstream ifs(_filename,ios_base::in|ios_base::binary);
        //需要傳入一個char*的字符串,然后第二個參數(shù)是要讀取的數(shù)據(jù)的大小
        ifs.read((char*)&info,sizeof(info));
    }
private:
    string _filename;

};
int main()
{//二進制的讀取
    ServerInfo rinfo;
    ConfigureManager cm;
    cm.ReadBin(rinfo);
    cout<

在這里插入圖片描述

二進制讀寫的坑

我們將這里的char*的address改成string,并且將這里的address的地址改成我們博客的連接

#include#includeusing namespace std;
struct ServerInfo
{//char _address[32];
    string _address;
    int _port;
};

struct ConfigureManager
{public:
    ConfigureManager(const char* filename="./server.config")
        :_filename(filename)
    {}

    void WriteBin (const ServerInfo& info)
    {//默認的寫都是覆蓋的模式進行寫入
        //但是app就是追加寫,也就是append
        ofstream ofs(_filename,ios_base::out|ios_base::binary);
        //需要傳入一個char*的字符串,然后第二個參數(shù)是要讀取的數(shù)據(jù)的大小
        ofs.write((char*)&info,sizeof(info));
    }

    void ReadBin (const ServerInfo& info)
    {//默認的寫都是覆蓋的模式進行寫入
        //但是app就是追加寫,也就是append
        ifstream ifs(_filename,ios_base::in|ios_base::binary);
        //需要傳入一個char*的字符串,然后第二個參數(shù)是要讀取的數(shù)據(jù)的大小
        ifs.read((char*)&info,sizeof(info));
    }
private:
    string _filename;

};
int main()
{//二進制寫出去
//    ServerInfo info={"https://editor.csdn.net/md/?articleId=128086656",888};
//    ConfigureManager cm;
//    cm.WriteBin(info);
    //二進制的讀取
    ServerInfo rinfo;
    ConfigureManager cm;
    cm.ReadBin(rinfo);
    cout<

我們先將數(shù)據(jù)寫出去,然后重新讀取進來。
(如果我們的address比較短的話,是不會報下列的錯誤的,但是如果address比較長的話,就會報下面的錯誤)
在這里插入圖片描述

在windows下的string,短的時候存的就·直接用共這里的_buff[16]將其進行存儲,如果這里的字符串太長了,就用string中的_ptr指向這個string的地址。
_buff[16]
_ptr
_size
_capacity
_port

ServerInfo info={"https://editor.csdn.net/md/?articleId=128086656",888};

字符串是存在我們的堆上面的,我們將我們的字符串寫出去,也就是調(diào)用write寫出去的時候,調(diào)用的是這個字符串的地址。這里我們的是分兩次運行的,也就是我們寫二進制文件的時候,這個字符串的地址。當(dāng)我們的讀的進程結(jié)束之后,我們再運行讀取的進程,我們將這個指針讀取回來的時候,這個指針已經(jīng)不是我們剛剛那個string的指針了!它已經(jīng)是一個野指針了?。?/p>

所以二進制讀寫的時候,一定要用數(shù)組,char[],不要使用string!!

文本的方式寫和讀取
#include#includeusing namespace std;
struct ServerInfo
{string _address;
    int _port;
};

struct ConfigureManager
{public:
    ConfigureManager(const char* filename="./server.config")
        :_filename(filename)
    {}

    void WriteText(const ServerInfo& info)
	{//這里我們將指定的文件進行寫的操作
		ofstream ofs(_filename, ios_base::out);
		//我們需要傳入一個寫入的子串和這個字符串的大小
		ofs.write(info._address.c_str(), info._address.size());
		//然后我們可以用換行將我們的字符串和后面的內(nèi)容進行分隔
		//當(dāng)然這里傳入一個換行符的話,我們可以使用上面的write,或者是下面的這種簡單形式的put
		ofs.put('\n');
		//將我們的_port,(原本是整型)轉(zhuǎn)換成字符串的類型
		const string str = to_string(info._port);
		//然后將我們的_port的字符串輸出,第一個人參數(shù)是字符串,第二個參數(shù)是字符串的大小
		ofs.write(str.c_str(), str.size());
	}

	void ReadText(ServerInfo& info)
	{//讀取指定的文件
		ifstream ifs(_filename, ios_base::in);
		//創(chuàng)建一個字符串緩沖區(qū)
		char buff[128];
		//讀取一行,放入我們上面剛剛創(chuàng)建的buffer當(dāng)中
		ifs.getline(buff, 128);
		//然后將我們的address中的內(nèi)容賦值成buff
		info._address = buff;
		//然后我們再讀取進來一行數(shù)據(jù)
		ifs.getline(buff, 128);
		//然后將我們的_port,因為它原本是整型,我們需要將其重新轉(zhuǎn)換成整型然后賦值給_port
		info._port = stoi(buff);
	}
private:
    string _filename;

};
int main()
{//文本方式寫出去
    ServerInfo info={"127.0.0.1",888};
    ConfigureManager cm;
    cm.WriteText(info);
    //文本方式讀進來
    ServerInfo rinfo;
//    ConfigureManager cm;
    cm.ReadText(rinfo);
    cout<

可以成功將文本寫出,并且正常讀取
在這里插入圖片描述
可以讀取到我們的文本中的內(nèi)容

在這里插入圖片描述

但是這樣的的方式非常麻煩,我們需要在寫入的時候手動成員的每一個參數(shù)轉(zhuǎn)換成字符串類型,再讀取的時候,還要將讀取到的字符串轉(zhuǎn)換成對應(yīng)的類型放入我們的成員中。
所以我們可以用C++給我們提供的文件流的讀和寫來幫助我們進行上述操作。

文件流寫和讀(c++)
#include#includeusing namespace std;


class Date
{//如果是自定義類的話,我們需要重載流插入和流提取
    friend ostream& operator<< (ostream& out, const Date& d);
    friend istream& operator >>(istream& in, Date& d);
public:
    Date(int year = 1, int month = 1, int day = 1)
            :_year(year)
            , _month(month)
            , _day(day)
    {}
    operator bool()
    {// 這里是隨意寫的,假設(shè)輸入_year為0,則結(jié)束
        if (_year == 0)
            return false;
        else
            return true;
    }
private:
    int _year;
    int _month;
    int _day;
};
istream& operator >>(istream& in, Date& d)
{in >>d._year >>d._month >>d._day;
    return in;
}
ostream& operator<< (ostream& out, const Date& d)
{out<< d._year<< " "<< d._month<<" "<< d._day ;
    return out;
}
struct ServerInfo
{string _address;
    int _port;
    Date date;
};

struct ConfigureManager
{public:
    ConfigureManager(const char* filename="./server.config")
        :_filename(filename)
    {}
    void WriteText(const ServerInfo& info){ofstream  ofs(_filename,ios_base::out);
        //這里我們流插入一個成員,我們最好加一個換行或者空格
        //這樣可以防止我們的流提取的時候,讀取到的數(shù)據(jù)粘連在一起
        ofs<ifstream ifs(_filename,ios_base::in|ios_base::binary);
        ifs>>info._address>>info._port>>info.date;
    }
private:
    string _filename;

};
int main()
{//二進制寫出去
//    ServerInfo info={"127.0.0.1",888};
    ServerInfo info={"127.0.0.1",888,{2022,11,30}};
    ConfigureManager cm;
    cm.WriteText(info);
    //二進制的讀取
    ServerInfo rinfo;
//    ConfigureManager cm;
    cm.ReadText(rinfo);
    cout<

文本方式讀寫的文件是可以直接進行查看的

在這里插入圖片描述

然后我們也是可以正常讀取到的

在這里插入圖片描述

四、istringstream 序列化和反序列化 ostringstream和istringstream
#includeusing namespace std;
class Date
{friend ostream& operator<< (ostream& out, const Date& d);
    friend istream& operator >>(istream& in, Date& d);
public:
    Date(int year = 1, int month = 1, int day = 1)
            :_year(year)
            , _month(month)
            , _day(day)
    {}
    operator bool()
    {// 這里是隨意寫的,假設(shè)輸入_year為0,則結(jié)束
        if (_year == 0)
            return false;
        else
            return true;
    }
private:
    int _year;
    int _month;
    int _day;
};
istream& operator >>(istream& in, Date& d)
{in >>d._year >>d._month >>d._day;
    return in;
}
ostream& operator<< (ostream& out, const Date& d)
{out<< d._year<< " "<< d._month<<" "<< d._day ;
    return out;
}
struct ChatInfo
{string _name; // 名字
    int _id; // id
    Date _date; // 時間
    string _msg; // 聊天信息
};

int main()
{//序列化
    ChatInfo winfo={"催逝員",114514,{2022,11,30},"啊哈哈哈哈,雞湯來嘍,哈哈哈"};
    //對應(yīng)的是sprintf
    ostringstream oss;
    oss<>rInfo._name;
    iss>>rInfo._id;
    iss>>rInfo._date;
    iss>>rInfo._msg;

    cout<<"------------------------------------------"<

在這里插入圖片描述

stringstream

在庫中stringstream繼承了istringstream和ostringstream的功能,所以直接調(diào)用這個stringstream就可以了

我們可以將我們上面的代碼修改如下

#includeusing namespace std;
class Date
{friend ostream& operator<< (ostream& out, const Date& d);
    friend istream& operator >>(istream& in, Date& d);
public:
    Date(int year = 1, int month = 1, int day = 1)
            :_year(year)
            , _month(month)
            , _day(day)
    {}
    operator bool()
    {// 這里是隨意寫的,假設(shè)輸入_year為0,則結(jié)束
        if (_year == 0)
            return false;
        else
            return true;
    }
private:
    int _year;
    int _month;
    int _day;
};
istream& operator >>(istream& in, Date& d)
{in >>d._year >>d._month >>d._day;
    return in;
}
ostream& operator<< (ostream& out, const Date& d)
{out<< d._year<< " "<< d._month<<" "<< d._day ;
    return out;
}
struct ChatInfo
{string _name; // 名字
    int _id; // id
    Date _date; // 時間
    string _msg; // 聊天信息
};

int main()
{//序列化
    ChatInfo winfo={"催逝員",114514,{2022,11,30},"啊哈哈哈哈,雞湯來嘍,哈哈哈"};
    //對應(yīng)的是sprintf
    stringstream oss;
    oss<>rInfo._name;
    iss>>rInfo._id;
    iss>>rInfo._date;
    iss>>rInfo._msg;

    cout<<"------------------------------------------"<

在這里插入圖片描述

你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機房具備T級流量清洗系統(tǒng)配攻擊溯源,準確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級服務(wù)器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧


文章名稱:C++【IO流】-創(chuàng)新互聯(lián)
新聞來源:http://weahome.cn/article/deshos.html

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部