C++硬核:從字元到字串流,這些年你還記得字串的108種用法嘛?

2020-08-13 08:31:19

C++硬核:從字元到字串流,這些年你還記得字串的108種用法嘛?

本文較爲全面地總結了字串輸入和輸出,以及C++常用函數等知識內容,供讀者學習參考,有錯誤不嚴謹之處請評論指出!·原創不易,收藏點贊一波唄~ヾ(*ΦωΦ)ツ

在这里插入图片描述

Ⅰ.字元陣列

字元的定義和分類

如果一個數組的元素爲字元型數據,則稱爲字元陣列。

字元的分類有以下4種:

  • 字母:a,b,c…z
  • 數位:0,1,2,9
  • 標點:+,-,*,/,;等等
  • 控制字元:Tab, Enter,Space等等

字元陣列賦初值的方法

1.單個字元方式

char names1[4];
name1={'x','c','a','s'};

注意這裏的括號是{}而不是()

2.字串常數方式

char names2[4];
name2="xcas";//字元個數小於等於4

注意字元個數應小於等於分配的字元空間個數大小

字元陣列的輸入和輸出

1.單個字元方式

char name1[5];
for(char & i : name1){
    cin>>i;
}//輸入
for(char i : name1){
    cout<<i;
}//輸出
cout<<endl;

2.整個字串方式

char name1[5];
cin>>name1;//直接cin>>name1;
cout<<name1<<endl;//直接cout<<name1;

注意使用cin>>和cout<<進行輸入輸出連續多個字元陣列的時候會出現亂碼異常等錯誤。。。

Ⅱ.字串變數

字串變數的定義:

string 變數名1,變數名2…變數名n;

string str1,str2;
string str3="hello,world!";

對字串變數,既可以整體使用,也可以使用其中的某個字元

 string a="sa";
 char b=a[1];
 cout<<b<<endl;

可以用如下方式在定義字串變數的同時爲其賦初值:

string  str4("computer");
string  str5(str4);
string  str6(5,'A');
string  str7("computer",12);//等價於 "computer" 存入str7中,最多儲存12個位元組
string  str8(8,'A')//儲存8個 'A' 到 str8中

字串陣列的定義:

字串陣列定義:
string陣列名[陣列長度];

string bookName[5];//定義
string stu[3]={"std","sq1","sq2"};//賦初值

字串變數的輸入和輸出:

通過鍵盤給字串變數輸入值

cin>>str;

把字串變數中的值輸出:

cout<<str;

從鍵盤輸入字串數據時,讀取並捨棄開始的空白字元;讀取可顯示字元並存入字串變數至再次遇到空白字元結束讀取操作。

如果從鍵盤輸入的是」 Happy New Year!;則輸出的結果是:Happy,不包含任何空格。

也可以使用只以換行符作爲分隔符的getline函數:

string str;
getline(cin,str);
cout<<str;

此時的空格不再作爲分隔符,而是一個普通的字元存放到字元變數str中。

getline函數還允許程式設計人員指定分隔符:

getline(cin, str,',');

此時指定逗號(,)也是輸入字串的分隔符。

字串的運算和比較:

字串連線(+)

把兩個字串拼接在一起形成一個新的字串。

字串連線規則如下

兩個字串變數可以進行連線操作

②兩個字串常數不能進行連線操作。

連線運算子(+)的兩個運算物件中至少有一個是字串變數還必須是前者是變數字串。

string str1("aqs"),str2;
str2=str2+str1;//變數字串+常數字串√,常數字串+變數字串×
cout<<str2;

字串的比較

字串比較運算子:>、>=、<、<=、!=。

字串str1和str2比較的依據是字元的 ASCII碼值

如果str1和str2的長度相等,而且各對應字元也完全相同,則認爲兩串相等

如果str1和str2的對應字元不完全相同,則比較第一對不相同字元的ASCI碼值,ASCI碼值小的字元所在串小

如果str1的長度n1小於str2的長度n2,而且兩個字串的前n1個對應字元都相同,則認爲str1小

Ⅲ.字串的輸入輸出常見方法的總結及解釋

a:getchar()與putchar()

#include <stdio.h>
using namespace std;
int main(){
    char ch;
    ch=getchar();//輸入單個字元;
    putchar(ch); //輸出單個字元;
    return 0;
}

getchar()讀取字元過程的細節

getchar() 用於讀取使用者從鍵盤輸入的單個字元,它有一個整型的返回值,當發生讀取錯誤的時候,返回整型值-1;當讀取正確的時候它會`返回使用者從鍵盤輸的第一個字元的ASCII碼。

當程式呼叫getchar時,執行程式時就等着使用者從按鍵輸入,使用者輸入的字元被存放在鍵盤緩衝區中,直到使用者按回車爲止(回車字元也放在緩衝區中),當使用者鍵入回車之後,getchar纔開始從輸入流中每次讀入一個字元。

輸入的字元不只一個的時候單個的getchar函數輸入多於一個字元時,只接收第一個字元。

putchar()讀取字元過程的細節

putchar()向終端輸出一個字元,其格式爲putchar(ch)。

其中ch可以是被單引號(英文狀態下)引起來的一個字元(注:該字元也可爲跳脫字元)可以是介於0到127之間的一個十進制整型數(包含0和127)(超過127就不是ASCII碼了),也可以是事先用char定義好的一個字元型變數

當c爲一個被單引號(英文狀態下)引起來的字元時,輸出該字元(注:該字元也可爲跳脫字元);當ch爲一個事先用char定義好的字元型變數時,輸出該變數所指向的字元;當ch爲一個介於0~127(包括0及127)之間的十進制整型數時,它會被視爲對應字元的ASCII程式碼,輸出該ASCII程式碼對應的字元。當整型變數ch超出8位元變數的範圍時,ch則會變強制轉化爲8位元變數(即取其低八位傳過去輸出),當爲負數的時候,由於計算機儲存負數是用補碼錶 碼表示的,所以傳過去的二進制二補數也被當做正數處理,也是取其低八位。

getchar()和putchar()的特性

  • 使用時,必須包含標頭檔案「#include <stdio.h>」
  • getchar()與putchar()不會忽略任何一個字元,包括換行 ,tab,enter在內
  • 只輸入輸出單個字元

b:scanf()與printf()

字串的讀取和輸出

使用%s格式化輸入輸出字串:

char a[100],b[100];
scanf("%s",&a);
scanf("%s",&b);
printf("%s",a);
printf("%s",b);

單個字元的讀取和輸出

使用%c格式化輸入輸出單個字元:

char a,b,c;
scanf("%c%c%c",&a,&b,&c);
printf("%c%c%c",a,b,c);

scanf()和printf()的特性

  • scanf()以非空白符開始,空白符結束,完成一個%s的錄入; printf()從當前位置列印到‘\0’結束。(連續輸入輸出多個字串不會受到"\n"(換行符)的影響!)
  • %c格式化單個字元,%s格式化輸入輸出整個字串
  • 使用時,需包含"#include<stdio.h>「或者」#include"。
  • scanf()和printf()僅支援字元陣列,不支援string型別元素

c:gets()與puts()

gets()與puts()均不支援string型別元素,範例如下:

char a[100];
//string a;  報錯,不支援string型別元素;
gets(a);
puts(a);

gets()和puts()的特性:

  • gets()類似於於scanf()+%s,接受tab和space鍵,只對Enter敏感
  • puts效果與printf()+%s效果一致,均爲從當前指針輸出至’\0’。
  • gets()和puts()僅支援字元陣列,均不支援string型別元素

d:cin>>與cout<<

見本文"Ⅰ.字元陣列->字元陣列的輸入和輸出"小節的內容,參考用法。支援連續多個字元陣列的使用。

使用連續字元陣列輸入輸出範例,如下:

#include <iostream>
using namespace std;
int main() {
    char name1[10],name2[10];
    cin>>name1;
    cout<<name1<<endl;
    cin>>name2;
    cout<<name1<<endl;
    cout<<name2;
    return 0;
}

cin>>與cout<<的特性:

  • 同時支援字元陣列、字串、字串陣列多個型別數據的輸入輸出
  • 支援連續多個字元陣列的輸入輸出使用
  • 根據後面的變數的型別讀取數據,讀取時結束條件:enter, space, tab,對結束符的處理:丟掉。
  • 當定義多個字元陣列時,分配的陣列空間要大一些,避免字元陣列中元素溢位

e:cin.get()與getline()

cin.get()不支援連續多行字元陣列的問題的解決:

原始碼支援輸入格式:「ab」,程式碼如下:

    char c1, c2;
    cin.get(c1);
    cin.get(c2);
    cout<<c1<<" "<<c2<<endl; // 列印兩個字元
    cout<<(int)c1<<" "<<(int)c2<<endl; // 列印這兩個字元的ASCII值
    return 0;

使用==cin.get().get()==修改後支援輸入格式:「a b」和"a"+"\n"+"b"

    char c1, c2;
    cin.get(c1).get();
    cin.get(c2);
    cout<<c1<<" "<<c2<<endl; // 列印兩個字元
    cout<<(int)c1<<" "<<(int)c2<<endl; // 列印這兩個字元的ASCII值
    return 0;

getline()支援從緩衝流中獲取剩餘的字元:

  • cin.rdstate():返迴流狀態;
  • cin.clear():狀態位清零;
  • cin.failbit():如果輸入操作未能讀取預期的字元或輸出操作沒有寫入預期的字元,設定爲1
    char str[20];
	//輸入提示:abcdefg
    cin.getline(str,5);
    cout << str << endl;//輸出:abcd
    cout << "read state: " << cin.rdstate() << endl;//read state: 4
    cin.clear(cin.rdstate() & ~cin.failbit);
    cout << "read state: " << cin.rdstate() << endl;//read state: 0,繼續讀取剩餘的字元流
    cin.getline(str,5);
    cout << str << endl;//輸出:efg
    return 0;

getline函數允許程式設計人員指定分隔符:

getline(cin, str,',');

cin之後使用getline()會出現空行問題的解決:

呼叫cin.ignore()即可,程式碼如下:

int n;
cin >> n;
cin.ignore(); 
string c;
getline(cin, c);
cout << c << endl;

cin.get()與getline()的特性:

  • 相同點:cin.getline()與cin.get()函數都可以讀取整行的字串都可指定讀取多少個字元到陣列,讀取完後剩餘的字元放在流中。
  • 區別:cin.getline() 能夠讀取回車鍵,並將之轉化爲換行符。這樣就不會留一個回車鍵在輸入流而對下一個字串的輸入造成影響。而cin.get()不能夠讀取回車鍵,而是將其繼續留在輸入流中,這樣有個弊端就是回車鍵會對下一個回車鍵造成影響。
  • getline(&address,&string)支援指定輸入的起始地址位置例如:string c;getline(cin, c);而cin.get()不支援指定地址位置輸入字串。
  • getline函數允許程式設計人員指定分隔符
  • getline()支援從緩衝流中獲取剩餘的字元

Ⅳ.字串流

字串流的定義和分類

字串流,即記憶體中的輸入輸出。分爲以下三類:

  • istringstream(輸入流)
  • ostringstream(輸出流)
  • ofstream(檔案流)

ofstream和ostringstream字串流的範例:

#include <iostream>
#include <fstream>
#include <sstream>
using namespace std;
int main(){
    //cout是輸出流物件,ostream
    cout <<"hello!"<<endl;
    //ofs是檔案輸出流物件,ofstream
    ofstream ofs("test. txt");
    ofs <<"hello!"<<endl;
    ofs.close();
    //字串輸出流物件--->記憶體
    ostringstream oss;
    oss<<"hello!"<<endl;
    cout<<"顯示字串流中的字串:"<<oss.str()<<endl;
       return 0;
}

cout是輸出字元流物件ostream,ofs是檔案輸出流物件,oss.str()用於獲取流物件oss中的內容。

從ostringstream獲取字串內容輸入至istringstream的範例:

#include <iostream>
#include <fstream>
#include <sstream>
using namespace std;
int main(){
    ostringstream formatmessage;
    formatmessage<<"姓名:"<<"張飛"<<"\n"
                <<"體重:"<<65.1<<"\n"
                <<"年齡:"<<26<<"\n";
    cout<<"輸出張飛的資訊:\n"<<formatmessage.str()<<endl;

    string name,kg,age,buff;
    istringstream input_istring(formatmessage.str());
    cout<<"iostream結果如下:"<<endl;
    input_istring>>name;
    cout<<name<<endl;
    input_istring>>kg;
    cout<<kg<<endl;
    input_istring>>age;
    cout<<age<<endl;

    return 0;
}

Ⅴ.C++中的String的常用函數用法總結

這個部分,已有部落格較爲完整的總結了現有的C++的string的常用函數,這裏我便不再贅述。

請參考該篇部落格

C++中的String的常用函數用法總結

Ⅵ.附表

跳脫字元及其作用表

在这里插入图片描述

scanf格式化字串表

在这里插入图片描述

注意%c類似於getchar(),不會跳過任何一個字元,包括空格,tab,‘\n’等。

printf格式化字串表

在这里插入图片描述

緩衝流(stream)狀態表

在这里插入图片描述

Ⅶ.參考

1.C++中cin和cout中不會被注意的細節(字串的處理)

2.C++中的cin函數和異常的來源(failbit)與處理(clear)

3.C++字元型陣列常用函數

4.C++字元型陣列常用函數

5.C++——String類超詳細介紹

6.C++中的幾種字串輸入輸出方法

7.C語言中的getchar()與putchar()詳解

8.C++中 cin的深入理解

9.《C語言-C++學習指南》5.1-字元的概念和使用

10.C++字串和字元陣列運用 第四講