C++ 檔案流、字串流、字元數組、字串

來源:互聯網
上載者:User

在開講之前,先給大家看下面這段C++代碼。

 

// definition of function read_file<br />//<br />// return the file's data in string<br />string read_file( string file_name = "test_data.txt" )<br />{<br />ifstream file( file_name.c_str() );<br />ostringstream file_data;<br />char temp;<br />if ( file.is_open() == true )<br />{<br />while ( file.peek() != EOF )// traversing the file<br />{<br />file.get( temp );// read the data one character by another<br />file_data << temp;<br />}<br />}<br />file.close();// Be Aware!Remember to close the file!<br />return file_data.str();<br />}

 

這個函數的功能是,從別處得到一個檔案名稱,然後開啟這個檔案,把裡面的內容逐個字元讀入一個string裡面,並且返回那個string。
那麼,為什麼要提這個程式呢?因為其涉及了4個容易混淆的概念:檔案流、字串流、字串、字元數組。

1、檔案流
1.1 概念
在C++中,對檔案的操作是通過stream的子類fstream(file
stream)來實現的,所以,要用這種方式操作檔案,就必須加入標頭檔fstream.h。本人習慣#include <fstream>
1.2 初始化
在實際應用中,根據需要的不同,選擇不同的類來定義:如果想以輸入方式開啟,就用ifstream來定義;如果想以輸出方式開啟,就用ofstream來
定義;如果想以輸入/輸出方式來開啟,就用fstream來定義。
在上面的函數,我為了讀取檔案,用ifstream構造了一個file,並且存入一個檔案名稱(字串數群組類型)作為參數。
1.3 開啟檔案
一般來說,可以顯式地開啟檔案,請自行百度+GOOGLE。
1.4 讀寫檔案
讀寫檔案分文字檔和二進位檔案,這裡談的是文字檔。
文字檔的讀寫很簡單:用插入器(<<)向檔案輸出;用析取器(>>)從檔案輸入。比如test_data.txt裡面有:
line1
line2
那麼我們可以這樣寫:
ifstream file( file_name.c_str() );
string s1,s2;
file >> s1 >> s2;
就能得到s1 = "line1" , s2 = "line2"。
但是,這樣無法讀出空格或者分行符號,所以我用了另外一種方法:file.get( temp )。這樣一來,temp就會逐個逐個字元地讀下去。
1.5 EOF結束檔案讀入。

2、字串流
2.1 概念
C++引入了ostringstream、istringstream、stringstream這三個類,要使用他們建立對象就必須包含
sstream.h標頭檔。
istringstream類用於執行C++風格的串流的輸入操作。
ostringstream類用於執行C風格的串流的輸出操作。
strstream類同時可以支援C風格的串流的輸入輸出操作。
2.2 個人理解
字串流與字串比較:字串在標準輸入輸出(cin,cout)中,總是以空格或者換行結束,但是字串流能接納多個字元或者字串,包括空格或者換
行。所以才有上面的
file_data << temp;
其中file_data是以ostringstream定義的,相當於一個螢幕的緩衝區,把一個個temp的字元接住。
2.3 字串流轉化為字串,如上面:
file_data.str();

3、字元數組與字串
3.1 糾結的ERROR
先看下面的樣本:
fstream file1( "1.txt" ); // OK!
string s = "1.txt";
fstream file2( s ); // ERROR!
是不是很糾結?同樣是"1.txt",直接放進建構函式就可以,變成string後就不可以。這說明什麼呢?C++中string類型與"..."表示的
字串不嚴格相等!
3.2 高人的文章,感謝!原文地址:http://yexin218.javaeye.com/blog/486080

在C中,並沒有字串這個資料類型,而是使用字元數組來儲存字串。C字串實際上就是一個以null('/0')字元結尾的字元數組,null字元表示
字串的結束。需要注意的是:只有以null字元結尾的字元數組才是C字串,否則只是一般的C字元數組。

C字串定義時可以利用"="號進行初始化,但是以後不能利用"="對C字串進行賦值。對C字串的操作需要通過"string"檔案中定義的字串處
理函數。例如:
//字串的初始化
char a[11] = "huanying";
//字串的賦值
strcpy(a,"nihao")
// 擷取字串的長度,不包括'/0'在內
strlen(a);
printf("%s",a);

在C中也可以使用字元指標來訪問一個字串,通過字元指標指向存放字串數組的首元素地址來進行訪問.
char *a = "nihao";
printf("%s",a);

在C++中則把字串封裝成了一種資料類型string,可以直接聲明變數並進行賦值等字串操作。以下是C字串和C++中string的區別:

C字串                     string對象
所需的標頭檔名稱       <string>或<string.h>        
<string>或<string.h>
為什麼需要標頭檔       為了使用字串函數            為了使用string類
如何聲明                  char name[20];              string name;
如何初始化                char name[20]="nihao";   string name = "nihao";
必須聲明字串長度嗎? 是                               否
使用一個null字元嗎?    是                               否
怎樣實現字串賦值     strcpy(name,"John");         name = "John";
其他優點                   更快                            更便於使用,優選方案
可以賦一個比現有字元更  不能                           可以
長的字串嗎? 

C++常用字串函數
char s1[]="I am a student";
char s2[20]="teacher";
char s3[]="student";
int result;
char s4[20],*p;

(1)串長度 int strlen(char *str)
cout<<strlen(s1)<<endl;  輸出14
cout<<strlen(s2)<<endl;  輸出7

(2)串拷貝 char *strcpy(char *str1,char *str2)
strcpy(s4,s2);  //s4為"teacher"

(3) 串聯接 char *strcat(char *str1,char*str2)
strcat(s2,s3);  //s2為"teacherstudent"
//
注意:如果使用字元數組存放字串,strcat函數並不檢查第一個數組是否能夠容納第二個字串,這樣多出來的字串就會溢出到相鄰的儲存單元而出現問
題。

(4)串比較 int strcmp(char *str1,char *str) 
//比較的是對應字元的ASCII碼值,如果str1>str2,返回1
result=strcmp(s2,s3);   //result>0
result=strcmp(s2,s2);   //result=0
result=strcmp(s3,s2);   //result<0

(5)串定位 char *strchr(char *str,char ch)
p=strchr(s1,'s');    //找到返回字元在字串中的位置,否則返回-1
strcpy(p,s2);       //s1為"I am a teacher"

(6) 在一個串中尋找是否存在和另一個串相等的子串

(7)截取子串形成一個新串

字串的輸入
(1) 方法一:使用輸入操符來填充一個C字串變數
例如:
char a[80];
cin>>a;
註:以這種方式來讀取C字串時,會忽略最初的空白字元(空格、定位字元和分行符號),而且輸入會在下一個空格或者分行符號處停止。

(2)方法二:使用預定義函數getline擷取整行輸入(包括空格)
getline函數有兩個參數:第一個參數用於接收輸入的C字串變數;第二個參數用於規定getline最多能接收的字元個數。
例如:
char a[80];
cin.getline(a,80);
當遇到行結束的時候,輸入才會停止。

C++ string類的輸入
(1) 方法一:和C字串輸入的方法一相同。
(2)方法二:使用getline函數。
例如:
string a;
getline(cin,a);

string對象和C字串之間的轉換
可以將C字串儲存在string類型的變數中,例如:
char a[] = "nihao";
string b;
b=a;
但string對象不能自動的轉換為C字串,需要進行顯式的類型轉換,需要用到string類的成員函數c_str().
例如:
strcpy(a,b.c_str());

字串到數位轉換
atoi函數擷取一個C字串參數,返回對應的int值。如果參數不與一個int值對應,atoi就會返回0。atoi函數在檔案為cstdlib的庫
中。如果數字太大,不能轉換成int類型的值,可以使用atol將字串轉換為long類型的值。
例如:
atoi("1234");   //返回整數1234
atoi("#123");   //返回0

5、總結
字元數組與字串的區別才是真正的痛點,所有用法或者BUG的解決辦法都在網上找到,但是理解則很難,連上面那位仁兄也只能給出他遇到的不同的解決辦法。
希望有人看到了,可以跟帖告知!

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.