程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> C++_系列自學課程_第_4_課_string_《C++ Primer 第四版》,大學課程自學網

C++_系列自學課程_第_4_課_string_《C++ Primer 第四版》,大學課程自學網

編輯:C++入門知識

C++_系列自學課程_第_4_課_string_《C++ Primer 第四版》,大學課程自學網


  相信學習過計算機編程的人,基本應該都接觸過C語言,在C語言中處理字符串大家一定多遇到過,

也都知道處理字符串非常麻煩,而在C++裡面,由標准庫string類提供對可變長的字符串的支持。下面

來看看string類的特性。

 

1、使用的先決條件

  在使用標准庫之前必須包含相應的頭文件, 要使用string類型,就需要包含相應的頭文件,如下所示:

#include <string>

  在使用iostream的時候,我們未來引用iostream裡面的類,前面需要加上  std::  來表示引用的是標准

IO庫提供的功能,同樣在使用string類的時候,需要加上一個表示作用域的限制修飾的說明,如下所示:

std::string  str;    //定義一個string的對象str

  在每一次定義的時候都要這樣使用 std:: 很麻煩,C++提供了一種更方便的機制,如下:

using std::string;

  在源文件裡面加上上面這一句, 在使用的時候,就可以直接使用 string來定義對象,如下所示:

string  str;

 

2、string類的初始化

  string類提供了多種初始化方法:

  1)  string   str;  //初始化為空字符串, 調用默認構造函數,

  2)   string   str2="volcanol";  // 賦值初始化,復制str2為"volcanol"的一個副本,

  3) string str1("volcanol");     //直接初始化,調用初始化函,

  4) string str1="volcanol"

    string str2(str1);   //利用 string對象初始化string str對象

  5) string  str1(3,'c');  //初始化str1為"ccc",

 

3、string對象的讀寫

  可以利用iostream提供的輸入和輸出機制來對string對象進行操作。

  輸入:

string str;
cin>>str;

  這樣就可以通過標准輸入來輸入字符到string對象中, 要注意的是:

  A)  cin在輸入的的時候會忽略開始的空白符(空格,制表符,換行符),然後從非空白字符開始讀入

  B)  cin在輸入的時候,會在再次遇到空白字符後結束輸入。

    這裡的意思就是:  通過 cin>>str讀入的字符流不會包含 endl 換行符,因此如果要換行的話,就

需要自己添加換行符。

  同樣可以利用cout<<來輸出string對象,如下所示:

cout<<str<<endl;

下面是一段例子代碼:

#include <iostream>
#include <string>

using std::cin;
using std::cout;
using std::endl;
using std::string;

int main(int argc,char *argv[])
{
    string str;
    while(cin>>str)
        cout<<str<<endl;

    return 0;
}

執行情況如下所示:

[root@localhost cpp_src]# g++ test.cpp 
[root@localhost cpp_src]# ./a.out 
a  //輸入a 然後按回車鍵
a
ab //輸入ab,然後按下回車鍵
ab
    
aaa bbb ccc   //輸入aaa bbb  ccc  按下回車鍵
aaa
bbb
ccc

  按下 ctrl+d 就會退出上面的程序,  這裡while循環判斷 cin>>str 是否遇到 end-of-file 結束符,

當按下ctrl+d後, cin>>str 返回 false, 結束循環。

 

4、getline函數的使用

  通過調用 getline函數可以一次輸入一行, 這裡需要注意的是:getline不會忽略開始的換行符,而是會

忽略最後的換行符,而且getline在遇到 空格、制表符的時候,不會結束一行的輸入,直到遇到endl換行符。

  getline()接受兩個參數:  getline(cin, str);

Exp:

[root@localhost cpp_src]# cat test.cpp 
#include <iostream>
#include <string>

using std::cin;
using std::cout;
using std::endl;
using std::string;

int main(int argc,char *argv[])
{
    string str;
    while(getline(cin,str))
        cout<<str<<endl;

    return 0;
}

執行結果如下:

[root@localhost cpp_src]# g++ test.cpp 
[root@localhost cpp_src]# ./a.out 
aaa bbb ccc ddd //輸入aaa bbb ccc ddd按下換行
aaa bbb ccc ddd
//直接輸入換行

//直接輸入換行

12345 //輸入12345 按下換行
12345

  這裡需要注意的是: getline不會忽略一行開頭的換行符,而且輸入後在string對象最後不會加上endl換行符。

 

5、string的操作

  string類型提供了很多的操作, 下面我們來看一下:

  string  str;

  str.size();  返回str對象的長度

  str.empty(); 判斷str是否是空字符串

  str[n];  下標操作,取其中的一個字符

  str1 + str2;

  str2 =str1;

  str1 == str2

  還有 != ,  <, <=,  >,>= 這些比較操作,這些操作與整數型的操作的意義一樣,但是string的

比較是按照字典序,同時區分大小寫,  滿足下面的關系:A < a

  

Exp:  關於str.size() 函數計算的長度,

[root@localhost cpp_src]# cat test.cpp 
#include <iostream>
#include <string>

using std::cin;
using std::cout;
using std::endl;
using std::string;

int main()
{
    string str1;
    string str2;

    cout<<str1.size()<<endl;
    cout<<sizeof("")<<endl;

    return 0;
}

執行結果如下所示:

[root@localhost cpp_src]# g++ test.cpp 
[root@localhost cpp_src]# ./a.out 
0
1

  通過上面的例子可見, str.size()函數計算長度的時候並不包括最後的null字符'\0', 這一點需要注意。

 

  還有一個特殊的地方: 就是 sizeof對 str對象的計算,得到的結果,與str.size 得到的結果不一樣,

因此需要注意。如下代碼所示:

[root@localhost cpp_src]# cat test.cpp 
#include <iostream>
#include <string>

using std::cin;
using std::cout;
using std::endl;
using std::string;

int main()
{
    string str1;
    string str2;

    cout<<str1.size()<<endl;
    cout<<sizeof("")<<endl;
    cout<<sizeof(str1)<<endl;
    return 0;
}

  上面代碼的執行結果如下所示:

[root@localhost cpp_src]# g++ test.cpp 
[root@localhost cpp_src]# ./a.out 
0
1
4

  這裡是因為 string對象會保留4個字節來存儲string對象的長度。

 

Exp: 關於 str.empty()函數的使用

[root@localhost cpp_src]# cat test.cpp 
#include <iostream>
#include <string>

using std::cin;
using std::cout;
using std::endl;
using std::string;

int main()
{
    string str1;
    string str2;

    if(str1.empty())
    {
        cout<<"str1 is a empty string"<<endl;
    }
    else
    {
        cout<<"str1 is not a empty string"<<endl;
    }

    return 0;
}

  執行結果如下:

[root@localhost cpp_src]# g++ test.cpp 
[root@localhost cpp_src]# ./a.out 
str1 is a empty string

  這裡可以知道的是,如果string對象是一個空字符串,那麼 str.empty()函數返回true。

其實也可以通過 str.size( )==0 來判斷string對象是不是為空。因為 str.size()不會計算最後的 ‘\0'.

 

Exp: 關於 str[n] 的使用

[root@localhost cpp_src]# cat test.cpp 
#include <iostream>
#include <string>

using std::cin;
using std::cout;
using std::endl;
using std::string;

int main()
{
    string str1;
    str1="volanol";

    for(string::size_type i=0; i != str1.size(); i++)
    {
        cout<<str1[i]<<endl;
    }
    return 0;
}

執行結果如下:

[root@localhost cpp_src]# ./a.out 
v
o
l
a
n
o
l

  這個代碼使用了上面說的:  str1 = 字符串字面值的賦值方法, 同時使用了 str[n]的下標引用方法。

這裡有一點需要說明:  string::size_type 是定義在string庫中的類型,這個類型專門用來計算string的長度

的。  同時還有一點: string對象的下標從0開始,到 str.size - 1 結束,就是說:   0<= n <= str.size() - 1

 

  str[n]的下標還可以作為左值。如下所示:

[root@localhost cpp_src]# cat test.cpp 
#include <iostream>
#include <string>

using std::cin;
using std::cout;
using std::endl;
using std::string;

int main()
{
    string str("volcanol");
    cout<<"str is:"<<str<<endl;

    cout<<"after str[3]='y' the str is:";
    str[3]='y';
    cout<<str<<endl;

    return 0;
}

執行結果如下:

[root@localhost cpp_src]# ./a.out 
str is:volcanol
after str[3]='y' the str is:volyanol

 

Exp:  關於字符串的相加  str1 + str2

[root@localhost cpp_src]# cat test.cpp 
#include <iostream>
#include <string>

using std::cin;
using std::cout;
using std::endl;
using std::string;

int main()
{
    string str1;
    string str2("hi,");

    str1="volanol";
    
    string str3= str2+ str1;
    cout<<str3<<endl;

    return 0;
}

執行結果如下所示:

[root@localhost cpp_src]# g++ test.cpp 
[root@localhost cpp_src]# ./a.out 
hi,volanol

    這段代碼,演示了  string類型的 str1 + str2 的效果,同時演示了  string str("volcanol"); 這樣的直接初始化

方式。

  string對象的 + 操作可以與字符串字面值進行操作,如下:

Exp:

[root@localhost cpp_src]# cat test.cpp 
#include <iostream>
#include <string>

using std::cin;
using std::cout;
using std::endl;
using std::string;

int main()
{
    string str1;
    string str2("hi,");

    str1="volanol";
    
    string str3= str2+ str1;
    cout<<str3<<endl;

    string str4= str3 + "nice to meet you"; //字符串字面值 + 運算
    cout<<str4<<endl;

    return 0;
}

執行結果如下:

[root@localhost cpp_src]# g++ test.cpp 
[root@localhost cpp_src]# ./a.out 
hi,volanol
hi,volanolnice to meet you

  同時需要注意的是:  + 操作符使用的時候,其左、右操作必須有一個是 string對象,否則是錯誤的。

例如:

 1 #include <iostream>
 2 #include <string>
 3 
 4 using std::cin;
 5 using std::cout;
 6 using std::endl;
 7 using std::string;
 8 
 9 int main()
10 {
11     string str1;
12     string str2("hi,");
13 
14     str1="volanol";
15     
16     str1 = "hi," + str1;
17 
18     str2= "hi,"+"volcanol";
19 
20     cout<<str1<<endl;
21     cout<<str2<<endl;
22 
23     return 0;
24 }

編譯的情況如下所示:

[root@localhost cpp_src]# g++ test.cpp 
test.cpp: In function ‘int main()’:
test.cpp:18: 錯誤:操作數類型 ‘const char [4]’ 和 ‘const char [9]’ 對雙目 ‘operator+’ 而言無效
[root@localhost cpp_src]# 

  可以發現 18 行出現錯誤了, 說 const char[4] 和 const char [9] 不能用雙目運算符進行計算, 

原因上面的提示信息已經說的很明白了,const char類型不支持+ 操作。

 

關於書中的習題:

1、什麼是默認構造函數

  默認構造函數是類構造對象是默認調用的構造函數,如果用戶不編寫用戶自定義的構造函數,則系統

默認會提供一個默認的構造函數。

2、例舉三種初始化string對象的方法

  A:  string  str;  默認構造函數

     B :   string   str("volcnaol");   利用字符串字面值直接初始化

    string   str1(str);   利用string對象直接初始化

  C   string  str = "volcanol";  利用字符串字面值復制初始化

    string  str1 = str;  利用string對象復制初始化

  D:  string  str(3,  'c');  

方法D的例子如下:

[root@localhost cpp_src]# cat test.cpp 
#include <iostream>
#include <string>

using std::cin;
using std::cout;
using std::endl;
using std::string;

int main()
{
    string str(3,'9');
    cout<<str<<endl;

    return 0;
}

執行結果如下:

[root@localhost cpp_src]# g++ test.cpp 
[root@localhost cpp_src]# ./a.out 
999

3、 下面 s和s1的值分別是什麼

     string  s;  

  int main()

  {

    string s1;
      }

 

這裡 s和s1 都是空字符串,  這個地方考察了一個知識點未初始化的對象的初值是什麼。  string對象

不初始化就是空字符串。

     int   a;

     int main()

  {

       int  b;

     }

     如上面所示, 則 a = 0;   而b將會是一個隨機值。 這是因為全局的內置類型如果不初始化,則系統默認會

初始化為0,  而局部變量的內置類型就會是一個隨機值。因此變量在定義的時候最好要初始化一下,保證在使用

之前就是有一個值,可以避免一些莫名其妙的錯誤。

 

習題4、編寫程序實現從標准輸入每次讀入一行文本, 然後改下程序每次讀入一個單詞。

讀入一行的程序:

[root@localhost cpp_src]# cat test.cpp 
#include <iostream>
#include <string>

using std::cin;
using std::cout;
using std::endl;
using std::string;

int main()
{
    string str;
    getline(cin,str);
    cout<<str<<endl;


    return 0;
}

修改為讀入一個單詞:

#include <iostream>
#include <string>

using std::cin;
using std::cout;
using std::endl;
using std::string;

int main()
{
    string str;
    //getline(cin,str);
    cin>>str;
    cout<<str<<endl;


    return 0;
}

 

習題5: 編寫一個程序讀入兩個字符串,測試是否相等,如果不相等,則指出哪一個較大; 測試兩個是否等長,

如果不等長,則指出哪一個較長。

[root@localhost cpp_src]# cat test.cpp 
#include <iostream>
#include <string>

using std::cin;
using std::cout;
using std::endl;
using std::string;

int main()
{
    string str1;
    string str2;

    cin>>str1>>str2;
    cout<<"str1 is:"<<str1<<endl;
    cout<<"str2 is:"<<str2<<endl;

    if(str1==str2)
        cout<<"str1 == str2"<<endl;
    else if(str1 > str2)
        cout<<"str1 > str"<<endl;
    else
        cout<<"str1 < str2"<<endl;

    if(str1.size() == str2.size())
        cout<<"str1 and str2 have same length"<<endl;
    else if(str1.size() > str2.size())
        cout<<"str1 is longger than str2"<<endl;
    else
        cout<<"str1 is shorter than strw"<<endl;

    return 0;
}

 

習題6: 編寫一個程序讀入多個string對象,然後連接成1個更大的string對象輸出; 然後改下程序,將相鄰的string對象

用空格隔開。

[root@localhost cpp_src]# cat test.cpp 
#include <iostream>
#include <string>

using std::cin;
using std::cout;
using std::endl;
using std::string;

int main()
{
    string str1;
    string str2;
    string str3;
    string str4;

    cin>>str1>>str2>>str3>>str4;

    string str5;
    str5=str1 + str2 + str3 + str4;
    cout<<str5<<endl;


    return 0;
}

 

修改後的程序:

[root@localhost cpp_src]# cat test.cpp 
#include <iostream>
#include <string>

using std::cin;
using std::cout;
using std::endl;
using std::string;

int main()
{
    string str1;
    string str2;
    string str3;
    string str4;

    cin>>str1>>str2>>str3>>str4;

    string str5;
    str5=str1 +" "+ str2+" " + str3+" " + str4;
    cout<<str5<<endl;


    return 0;
}

7、下面的程序合法嗎,實現什麼功能

string s;
cout<<s[0]<<endl;

  合法,這個程序最終會輸出一個換行號。

    這個地方尤其要注意,我開始的時候也做錯啦,經過測試才知道是對的。

最後一個題目不做啦,下次補上。

 


在學習《c primer plus》的過程中出現一個段錯誤(超出了我的理解范圍)

scanf("%f",weight);少一個&符號
 

c primer plus 中提到的c庫是什

C庫就是C函數庫,是一些跨平台的函數,可以完成許多功能。C函數庫包含以下頭文件
<assert.h><complex.h><ctype.h><errno.h><fenv.h><float.h><inttypes.h><iso646.h><limits.h><locale.h><math.h><setjmp.h><signal.h><stdarg.h><stdbool.h><stddef.h><stdint.h><stdio.h>
<stdlib.h><string.h><tgmath.h><time.h><wchar.h><wctype.h>

像stdio這樣的功能,是要依賴平台的調用來實現的,比如文件操作,不同的操作系統有不同的函數,但是C標准庫為我們定義了一個統一的抽象接口,方便了我們的程序。

就比如說,同樣是都是安全軟件。如卡巴斯基,瑞星什麼什麼的。
但是只有騰訊電腦管家這種安全軟件可以做到跨越各種安全平台,為用戶電腦帶來各項例如查殺病毒、電腦清理、電腦加速、電腦門診等的使用功能。
這下就明白了吧。
望采納哦。
 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved