C++ Primer第一章總結

關於main中的return:return 0表示正常狀態,return 非0數表示非正常(一般用return -1表示程序錯誤)。可是不論return多少,Win10/7貌似對於不處理錯誤標識。但是系統通過環境變量ERRORLEVEL記錄了上一個程序的返回值。

echo %ERRORLEVEL%

在這裏插入圖片描述


流(stream):字符序列。(隨着時間推移,順序生成/消耗) 注意流的性質(字符)(序列)。

  • cout,cin,clog(緩衝,將程序的執行信息存入日誌文件中),cerr(標準錯誤流,用法與cout差不多,用於輸出錯誤信息,通常寫入到與標準輸出流一樣的設備,不緩衝)皆爲流對象(stream object)
  • <<:該運算符將給定的值寫到給定的ostream對象輸出運算符的計算結果就是左側運算對象,而且順序從左至右。 (cout<<“Enter two num:”)<<std::endl;
    >>:該運算符將istream對象的值寫入規定的對象輸入運算符的計算結果依舊是左側對象,順序從左至右。
  • endl:是一個操作符(manipulator),endl的效果不僅換行,而且將與設備關聯的緩衝區中的內容刷新到設備中。它能夠保證所有內容寫入到輸出流(真正輸出),而不是僅停留在內存的緩衝區中。 將文件從緩衝區放入輸出流中還有很多方法,見C++ Primer282頁;

(這是我理解的模型:buffer作爲內存的一部分,與流進行連接,存儲還沒有送進流的內容;當內容還在buffer中,說明內容還沒有輸出;當內容放入stream中,則表示已經正在/完成傳輸)
在這裏插入圖片描述

#include <fstream>
#include <iostream>
#include <string>
using namespace std;
 
int main()
{
	ofstream out_file("test.txt", ofstream::trunc); 
 
	for (size_t i = 0; i != 5; ++i)
	{
		string t;
		cin >> t;
		out_file << t; 
	}
 
	return 0;
}
  • out_file<<t並沒有endl;實驗結果:只有在程序結束時,通過return 0將緩衝區的數據送入文件輸出流中,將內容寫入文件中;在中途(i!=5)時,文件沒有任何內容。
  • 如果out_file<<t有endl;那麼每一次out_file就會更新一次file。

#include <iostream>

using namespace std;

int main()
{
    int sum=0,value=0;
    while(cin>>value){
        sum+=value;
    }
    cout<<sum<<endl;
    return 0;
}
  • 類似於C中的while(scanf),在C++中也可以使用while(cin),通過alt+z停止輸入.

  • 當使用istream對象作爲條件時,效果是檢測流的狀態。如果流是有效的,即流未遇到錯誤,那麼檢測成功,循環繼續。當遇到文件結束符(end of file),或遇到一個無效輸入(要求輸入整數,卻輸入字符),istream對象無效。處於無效對象的istream使表達式爲假。 (和C的scanf不同,scanf是返回個數) (因此可以通過if,while語句來搭配cin來檢驗是否是正確的輸入)

  • 關於文件結束符(end of file,EOF):

    • 其值一般爲-1,關鍵在於EOF的值不能再char的表示範圍之內。(特殊字符)
    • 通過ctrl+z觸發。
    • 在Windows中,輸入用的是阻塞式檢查:只有在回車鍵按下之後,纔對輸入進行檢查;如果ctrl+z前面有輸入,將ctrl+z(包括自身)之前的內容放入緩衝區中(將之後的內容捨棄),並且等待下一次的輸入,一起輸出; 如果是單獨的ctrl+z,表示結束。(cin輸入可以當成是一個文件輸入,輸入ctrl+z表示文件結束)
#include <iostream>
#include<string>
using namespace std;

int main()
{
    string s;
    while(cin>>s){
        cout<<s<<endl;
    }
    return 0;
}

在這裏插入圖片描述

  • 實驗結果分析:
    • nmnnk^ Zhg:獲得nmnnk^ Z(^Z是ctrl+Z),hg捨去,第二次不輸入(直接回車),得到第三行的結果。
    • asd^ Zsdsd asdasd:首先獲得asd^Z,sdsd捨去,第二次輸入asdasd,將其連成一行,進行輸出。

提前實現第一章的對象輸入,輸出:操作符重載。

對於輸入輸出操作符的重載,適合將重載函數當成友元函數。(輸入輸出符只有一個對象(輸入或者輸出))

friend ostream &operator<<(ostream &out,Node *n);
friend istream &operator>>(istream &in,Node *n);

對於輸入輸出,返回值的流對象的狀態,因此返回值ostream/istream;還需要定義一個流對象(in/out);通過out<<和in>>,進行功能構造.

ostream &operator<<(ostream& out,Node* n){
    out<<n->n<<"  "<<n->m<<"  "<<n->s<<endl;
    return out;
}

istream &operator>>(istream& in,Node* n){
    in>>n->n>>n->m>>n->s;
    return in;
}


字符串截取:通過中的find查找位置,substr進行截取,stoi/stod進行類型的轉換;

string split_nms(string source_string,int& n,double& m){
    int place_one,place_two;
    string tmp_1,tmp_2,tmp_3;

    place_one=source_string.find("  ");
    place_two=source_string.find("  ",place_one+1);   //從place_one+1開始尋找,子串的第一個位置爲0

    tmp_1=source_string.substr(0,place_one);
    tmp_2=source_string.substr(place_one+2,place_two-place_one);
    tmp_3=source_string.substr(place_two+2,source_string.size()-place_two-1);


    n=stoi(tmp_1);  //string to int
    m=stod(tmp_2);  //string to double
    return tmp_3;
}

文件重定向:用文件作爲程序的輸入輸出。

使用方法:對於已編譯的程序( item.exe), 通過 $ item.exe <infile >outfile 來表示從哪個文件進行讀取,從哪個文件輸出。

(這個和文件流不一樣,文件流是在程序裏面,使用fstream;而重定向,是對於編譯後的程序,在命令行中使用命令,從而用文件代替標準輸入輸出流)
(重定向適合於測試,真正需要用到文件,還是需要使用文件流)


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