我的第一篇博客-----------------用stringstream…
2018-06-17 22:17:33来源:未知 阅读 ()
首先来看一个问题
国际标准图书编号(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 }
编写至此,产生一个新问题:这种方法繁琐,需要频繁写入流中,如何更有效率的截取字符串?
另外,如何把一个字符串分为众多的子串?在修改时便可不必反复截取,节省时间,节省精力!
笔者不精,偶有所得,文中若有不妥之处,欢迎前来指正!
若有此类想法或见解,亦欢迎前来交流!
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
上一篇:指针
- 结题报告 2020-03-07
- C++ 一篇搞懂多态的实现原理 2020-02-01
- 二进制枚举之被RE完虐的我的一天 2020-01-03
- C++ 一篇搞懂继承的常见特性 2020-01-01
- 究竟是什么毁了我的impl实现 2019-12-06
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash