differenct semantics between basic_istream::get and basic_istream::getline

basic_istream<Elem, Tr>& get(
Elem *str,
streamsize num,
Elem delim
);

basic_istream<Elem, Tr>& getline(
Elem *str,
streamsize num,
Elem delim
);



他们有着完全不同的语义.

#include <iostream>
using namespace std;

static const size_t Size = 5;

int main()
{
char buf[Size] = {'\0'};
int cnt = 0;

while (++cnt,
cin.get(buf, sizeof(buf)/sizeof(buf[0]))) // 每次读取 num - 1 个字符.
{
cout <<cnt <<": " <<buf <<endl;
}

cin.clear(); // 清除 ios_base::failbit. 使以后可以继续从 input stream 中读取数据.
cin.get(); // 手动清楚 input stream 中取出尚未取出的 '\n'

return 0;
}


                      (图 一 )

get 每次读取 num -1 个字符, 且不读取 delimiter. 如果没有遇到 delimiter, 就返回.

执行过程解释:

   程序通过 while 循环读取, 每次读取 4(Size - 1) 个字符. 刚开始 input stream 中有 "12345678901234\n"

       ....

   直到第 4 次循环时, input stream 中剩下了 "34\n" 这三个字符.

   get 函数执行读取, 当遇到 delmiter(即 '\n') 后不读取这个 delimiter 而直接返回, 并输出第 4 行读取结果: 34.

   此时 input stream 中只剩下了一个 "\n". 当再次执行 cin.get, input stream 中除了一个 delimiter("\n") 之外无其它数据, 这是导致 cin.get 出错的唯一条件. ios_base::failbit 被置位并返回. 此时 input stream 中 failbit 被设置. 为了今后继续读取

  • 首先需要调用 cin.clear() 清除标记位
  • 最后别忘了使用 cin.get() 手动清除 input stream 中的 delimiter.
 
// getline.cc
//

#include <iostream>
using namespace std;


static const size_t Size = 5;

int main()
{
char buf[Size] = {'\0'};
int cnt = 0;

while (++cnt,
cin.getline(buf, sizeof(buf)/sizeof(buf[0])))// 1.
{
cout <<cnt <<": " <<buf <<endl;
}
cin.clear(); // reset input state.

cout <<"place '1' has read: " <<buf <<endl;
cin.getline(buf, sizeof(buf)/sizeof(buf[0])); // 2.
cout <<"place '2' has read: " <<buf <<endl;

return 0;
}

 
                 (图 二)

                 (图 三)

getline 每次读取 num-1 num 个字符.

当 delimiter 位于 [0, num], 则读取至 delimiter 元素(包括 delimiter), 并去除读入的 delimiter, 添加 '\0' 至结果字串尾. 函数成功返回. (图二) 中 1, 2 输出.

当 delimiter 位于 (num, ∞), 则读取 num - 1 个元素, 并将 '\0' 添加至结果字串尾. 函数失败, 置位 ios_base::failbit. (图二) 中 3 输出, 以及(图三).

 

summary

函数名  读取字符 成功条件 失败条件 失败的标志位 特性
get num - 1 第一个字符不是 delimiter 第一个字符 delimiter ios_base::failbit 不会取出 input stream 中的 delimiter 
getline
  • num - 1: 当 delimiter 位于 [0, num) 位置时.
  • num: 当且仅当 delimiter 位于 num 时. 
delimiter 存在于 [0, num] 位置 delimiter 存在于 (num, ∞) ios_base::failbit 取出 input stream 中的 delimiter

 

posted @ 2012-03-15 23:25  walfud  阅读(763)  评论(1编辑  收藏  举报