擴展——String類--string類輸入

 對於C-風格字符串,有三種方式:

char info[100];
	cin>>info;			//read a word
	cin.getline(info,100);	//read a line, discard \n
	cin.get(info, 100);		//read a line, leave \n in queue

 對於string對象,有兩種方式:

	string stuff;
	cin>>stuff;			//read a wordgetline(cin,stuff);		//read a line, discard\n

兩個版本的getline()都有一個可選參數,用於指定使用哪個字符來確定輸入的邊界:

cin.getline(info,100,:);	//read up to :, discard :
getline(stuff,:);			//read up to :, discard :

在功能上,它們之間的主要區別在於,string版本的getline()將自動調整目標string對象的大小,使之剛好能夠存儲輸入的字符:

char fname[10];
string lname;
cin>>fname;		//could be a problem if input size >9 characters
cin>>lname;		//can read a very, very long word
cin.getline(fname,10);		//may truncate input
getline(cin,lname);		//no truncation

自動調整大小的功能讓string版本的getline()不需要指定讀取多少個字符的數值參數。
在設計方面的一個區別是,讀取C-風格字符串的函數是istream類的方法,而string版本是獨立的函數。這就是對於C-風格字符串輸入,cin是調用對象;而對於string對象輸入,cin是一個函數參數的原因。
這種規則也適用於>>形式,如果使用函數形式來編寫代碼,這一點將顯而易見:
cin.operator>>(fname); //ostream class method
operator>>(cin,lname); //regular function

下面更深入地探討一下string輸入函數。正如前面指出的,這兩個函數都自動調整目標string的大小,使之與輸入匹配。但也存在一些限制。

第一個限制因素是string對象的最大允許長度,由常量string::npos指定。這通常是最大的unsigned int值,因此對於普通的交互式輸入,這不會帶來實際的限制;但如果您試圖將整個文件的內容讀取到單個string對象中,這可能成爲限制因素。
第二個限制因素是程序可以使用的內存量。
string版本的getline()函數從輸入中讀取字符,並將其存儲到目標string中,直到發生下列三種情況之一:

  •  到達文件尾,在這種情況下,輸入流的eofbit將被設置,這意味着方法fail()和eof()都將返回true;
    
  •  遇到分界字符(默認爲\n),在這種情況下,將把分界字符從輸入流中刪除,但不存儲它;
    
  •  讀取的字符數達到最大允許值(string::npos 和可供分配的內存字節數中較小的一個),在這種情況下,將設置輸入流的failbit,這意味着方法fail()將返回true。
    

輸入流對象有一個統計系統,用於跟蹤流的錯誤狀態。在這個系統中,檢測到文件尾後將設置eofbit寄存器,檢測到輸入錯誤時將設置failbit寄存器,出現無法識別的故障(如硬盤故障)時將設置badbit寄存器,一切順利時將設置goodbit寄存器。
string版本的operator>>()函數的行爲與此相似,只是它不斷讀取,直到遇到空白字符並將其留在輸入隊列中,而不是不斷讀取,直到遇到分界字符並將其丟棄。空白字符指的是空格、換行符、製表符,更普遍的說,是任何將其作爲參數來調用isspace()時,該函數返回ture的字符。

程序清單16.2是一個從文件中讀取字符串的簡短示例,它假設文件中包含用冒號字符分隔的字符串,並使用指定分界符的getline()方法。然後,顯示字符串並給它們編號,每個字符串佔一行。

//strfile.cpp -- read strings from a file
#include<iostream>
#include<fstream>
#include<string>
#include<cstdlib>
int main() {
	using namespace std;
	ifstream fin;
	fin.open("tobuy.txt");
	if (fin.is_open() == false) {
		cerr << "Can't open file. Bye.\n";
		exit(EXIT_FAILURE);
	}
	string item;
	int count = 0;
	getline(fin, item, ':');
	while (fin)//while input is good
	{
		++count;
		cout << count << ": " << item << endl;
		getline(fin, item, ':');
	}
	cout << "Done\n";
	fin.close();
	return 0;
}

下面是文件tobuy.txt的內容:
sardines:chocolate ice cream:pop corn:leeks:
cottage cheese:olive oil:butter:tofu

通常,對於程序要查找的文本文件,應將其放在可執行程序或項目文件所在的目錄中;否則必須提供完整的路徑名。在Windows系統中,C-風格字符串中的轉義序列\表示一個斜槓
fin.open(“C:\CPP\Progs\tobuy.txt”); //file = C:\CPP\Progs\tobuy.txt
下面是程序清單16.2中程序的輸出:
在這裏插入圖片描述
注意,將:指定爲分界字符後,換行符將被視爲常規字符。
因此文件tobuy.txt中第一行末尾的換行符將成爲包含”cottage cheese”的字符串中的第一個字符。同樣,第二行末尾的換行符是第8個輸入字符串中的唯一的內容。

From《C++ Primer Plus》
By——Suki

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