设为首页 加入收藏

TOP

15.1.4 流式输入(2)
2013-10-07 15:35:20 来源: 作者: 【 】 浏览:66
Tags:15.1.4 流式 输入

15.1.4  流式输入(2)

2. 输入方法

与输出流一样,输入流也提供了一些方法,通过这些方法可以获得比普通>>运算符更底层的访问。

get()

get()方法允许从流中读入原始输入数据。get()最简单的版本返回流中的下一个字符,还有其他版本一次读入多个字符。get()常用于避免>>运算符的自动标志化。例如,下面这个函数从输入流中读入一个由多个词构成的名字,直到读到流尾。

  1. string readName(istream& inStream)  
  2. {  
  3. string name;  
  4. while (inStream.good()) {  
  5. int next = inStream.get();  
  6. if (next == EOF)  
  7. break;  
  8. name += next;// Implicitly convert to a char and append.  
  9. }  
  10. return name;  
  11. }  
  12.  
  13. 代码取自Get\Get.cpp  

在这个readName()函数中,有一些有趣的发现:

这个函数的参数是一个对istream的非const引用,而不是一个const引用。从一个流读入数据的方法会改变实际的流(主要改变当前位置),因为这些方法都不是const方法。因此,不能对const引用调用这些方法。

get()的返回值保存在一个int中,而不是一个char中。因为get()会返回一些特殊的非字符的值,例如EOF(文件尾),因此使用int。当next被追加到一个string的时候,被隐式地转换为一个char;如果被追加到一个wstring,则会被转换为一个wchar_t。

readName()有一点奇怪,因为可以采用两种方式跳出循环。一种方式是流进入"不好的"状态,另一种方式是达到流尾。另一种从流中读入数据的更常用的方法是使用另一个版本的get(),这个版本接受一个字符的引用,并且返回一个流的引用。这种模式利用了一个事实:在条件环境中对一个输入流求值的时候,只有当输入流可以用于下一次读取的时候才会返回true。如果遇到错误或者到达文件尾都会使得流求值为false。第18章讲解了实现这个特性所需要的转换操作的底层细节。同一个函数的下面这个版本稍微简洁一些:

  1. string readName(istream& inStream)  
  2. {  
  3. string name;  
  4. char next;  
  5. while (inStream.get(next)) {  
  6. name += next;  
  7. }  
  8. return name;  
  9. }  
  10.  
  11. 代码取自Get\Get.cpp  

unget()

对于大多数场合来说,理解输入流的正确方式是将输入流理解为一个单方向的滑槽。数据丢入滑槽,然后进入变量。unget()方法打破了这个模型,允许将数据塞回滑槽。

调用unget()导致流回退一个位置,将前一个读入的字符放回到流中。通过调用fail()方法可以查看unget()是否成功。例如,如果当前位置就是流的起始位置,那么unget()会失败。

本章前面出现的getReservationData()函数不允许输入一个带有空白字符的名字。下面的代码使用了unget(),允许名字中出现空白字符。这段代码逐字符读入,并检查字符是否为数字。如果字符不是数字,则将字符添加到guestName。如果字符是数字,则通过unget()将这个字符放回到流中,循环停止,然后通过>>运算符输入一个整数partySize。后面的"输入操作算子"小节将讨论noskipws的意义。

  1. void getReservationData()  
  2. {  
  3. string guestName;  
  4. int partySize = 0;  
  5. // Read letters until we find a non-letter  
  6. char ch;  
  7. cin >> noskipws;  
  8. while (cin >> ch) {  
  9. if (isdigit(ch)) {  
  10. cin.unget();  
  11. if (cin.fail())  
  12. cout << "unget() failed" << endl;  
  13. break;  
  14. }  
  15. guestName += ch;  
  16. }  
  17. // Read partysize  
  18. cin >> partySize;  
  19. cout << "Thank you '" << guestName 
  20. << "', party of " << partySize << endl;  
  21. if (partySize > 10) {  
  22. cout << "An extra gratuity will apply." << endl;  
  23. }  
  24. }  
  25.  
  26. 代码取自Unget\Unget.cpp  

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇15.1.4 流式输入(3) 下一篇15.1.4 流式输入(1)

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

·哈希表 - 菜鸟教程 (2025-12-24 20:18:55)
·MySQL存储引擎InnoDB (2025-12-24 20:18:53)
·索引堆及其优化 - 菜 (2025-12-24 20:18:50)
·Shell 中各种括号的 (2025-12-24 19:50:39)
·Shell 变量 - 菜鸟教 (2025-12-24 19:50:37)