我的第一篇博客-----------------用stringstream來實現字符串的截取


首先來看一個問題 

   國際標准圖書編號(I2017-07-05SBN)由被破折號分開的10個數字組成,如0-670-82162-4。一個ISBN分成四個部分:組代碼、出版社代碼、書籍代媽(在該出版社內惟一)、校驗碼 ,例如,ISBN 0-670-82162-4的含義是:組代碼是0,表明這本書來自說英語的國家;出版社代碼為670,標識這本書是由Viking Press發行的;82162是這本書在Viking Press的編號;校驗碼的計算方法如下所示:

  按如下方法計算一個總和:ISBN中第一個數字加上第二個數字的兩倍加第三個數字的三倍…,一直加到第九個數字的九倍為止。

  將上述總和除以11得到余數,如果余數為10,則最后一個特征值為X;如果不為10,則最后一個特征值就是這個余數。

  要求:設計一個類,類中有書名,ISBN,等信息,其中定義了類成員函數,要求通過函數對象,並輸入書的一切信息,同時設計一個函數來檢查ISBN是否正確;

  編寫代碼時遇到問題:如果ISBN校驗碼錯誤,如何修改字符串中的校驗碼?范圍再大一點,也就是說,如何修改字符串中指定位置的字符串?這是一個問題!

 

  對於上述問題給出以下思路:截取不需要修改的字符串並保存,定義新字符串並替換原來需要修改的子串,將新的多個字符串寫入流中,然后從流中寫到最終的正確的字符串。

  那么截取字符串,又該怎么做呢?網上搜尋字符串截取函數未果,便決定自己寫一個函數來實現。

  注意到stringstream的方便特性,便有了思路。通過將字符逐個寫入流中再統一寫到新字符串中去便可以實現;

  以下給出代碼:

  

 1 /*
 2     函數功能:字符串截取
 3     參數:字符串
 4     返回值:截取的字符串
 5 */
 6 string cutStr(string str,int begin, int end){
 7     stringstream stream;
 8     string newStr;
 9     stream.clear();
10     int i = 0;
11     for(i=begin; i<=end; i++){
12         stream<<str[i];
13     }
14     stream>>newStr;
15     return newStr;
16 }

 

  這樣就實現了字符串截取函數。

  最終問題得以解決:通過多次截取修改,便可以實現修改字符串指定位置上的字符

  以下為初始問題代碼: 

  1 #include<iostream>
  2 #include<string>
  3 #include<sstream>
  4 using namespace std;
  5 
  6 class BOOK{
  7 protected:
  8     string name;
  9     string author;
 10     string date;
 11     string ISBN;
 12     string price;
 13 public:
 14     //創建類對象
 15     BOOK create();
 16     //檢查ISBN
 17     void checkISBN();
 18     //打印
 19     void print();
 20 };
 21 
 22 
 23 /*
 24     函數功能:打印
 25     參數:無
 26     返回值:無
 27 */
 28 void BOOK::print(){
 29     cout<<"信息如下:"<<endl;
 30     cout<<"書名:"<<this->name<<endl;
 31     cout<<"作者:"<<this->author<<endl;
 32     cout<<"出版日期:"<<this->date<<endl;
 33     cout<<"ISBN:"<<this->ISBN<<endl;
 34     cout<<"價格:"<<this->price<<endl;
 35     cout<<"---------------------------------------------------------------"<<endl;
 36 }
 37 
 38 /*
 39     函數功能:字符串截取
 40     參數:字符串
 41     返回值:截取的字符串
 42 */
 43 string cutStr(string str,int begin, int end){
 44     stringstream stream;
 45     string newStr;
 46     stream.clear();
 47     int i = 0;
 48     for(i=begin; i<=end; i++){
 49         stream<<str[i];
 50     }
 51     stream>>newStr;
 52     return newStr;
 53 }
 54 
 55 /*
 56     函數功能:檢查ISBN
 57     參數:無
 58     返回值:正確的ISBN
 59 */
 60 void BOOK::checkISBN(){
 61     //寫一個字符串截取函數
 62     string ISBN = cutStr(this->ISBN,0,11);
 63     //0-670-82162-4
 64     //0123456789012
 65     stringstream stream;
 66     //用循環來計算校驗碼
 67     int i = 1;
 68     int j = 0;
 69     int sum = 0;
 70     int num = 0;
 71     while(i<=9 && j<=11){
 72         if(ISBN[j]=='-'){
 73             j++;
 74             continue;
 75         }else{
 76             stream<<ISBN[j];
 77             stream>>num;
 78             num = i * num;
 79             sum = sum + num;
 80             i++;
 81             j++;
 82             stream.clear();
 83         }
 84     }
 85 
 86 
 87     sum = sum%11;
 88     if(sum==10) sum=0;
 89     stream<<(this->ISBN)[12];
 90     stream>>num;
 91     stream.clear();
 92     //檢查並改正
 93     if(num != sum){
 94         stream<<ISBN<<sum;
 95         stream>>this->ISBN;
 96         cout<<"ISBM有誤,已幫您修改!"<<endl;
 97     }
 98     
 99 }
100 
101 /*
102     函數參數:創建類對象
103     參數:無
104     返回值:類對象
105 */
106 BOOK BOOK::create(){
107     BOOK book;
108     cout<<"書名:";
109     cin>>book.name;
110     cout<<"作者:";
111     cin>>book.author;
112     cout<<"出版日期:";
113     cin>>book.date;
114     cout<<"ISBN:";
115     cin>>book.ISBN;
116     cout<<"價格:";
117     cin>>book.price;
118     //檢查ISBN,如果錯誤提示改正
119     //寫一個檢查ISBN的函數
120     book.checkISBN();
121     cout<<"---------------------------------------------------------------"<<endl;
122     return book;
123 }
124 int main(){
125     BOOK book=book.create();
126     book.print();
127     return 0;
128 }

編寫至此,產生一個新問題:這種方法繁瑣,需要頻繁寫入流中,如何更有效率的截取字符串?

另外,如何把一個字符串分為眾多的子串?在修改時便可不必反復截取,節省時間,節省精力!

筆者不精,偶有所得,文中若有不妥之處,歡迎前來指正!

若有此類想法或見解,亦歡迎前來交流!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM