因为之前每次使用这个函数都要在网上查一遍,觉得很麻烦,这次就认真地整理一下,希望写完之后就记住。

getline函数其实有两个:

  一个是全局函数,include<cstring>, 原型是 istream& getline( istream& is, string& str, char delim) 与 istream& getline( istream& is, string& str) , 得到的字符串存在一个string类型的str里。

  另一个是iostream类的成员函数, include<iostream>, 原型是 istream& getline( char * str, streamsize n, char delim ) 与 istream& getline( char * str, streamsize n ) , 得到的字符串存在一个C-style字符数组str里。(值得注意的是,这个n应该小于字符数组str的长度,因为至少要留一个位置存放结束符'\0',后面这个还要探讨一下)

以后可以参考的cin.getline源码:

_Myt& getline(_Elem *_Str, streamsize _Count, _Elem _Delim)   
{// get up to _Count characters into NTCS, discard _Delim   
    _DEBUG_POINTER(_Str);    //判断传入指针的合法性  
    ios_base::iostate _State = ios_base::goodbit;    
    _Chcount = 0; //从输入流中读取的字符数  
    const sentry _Ok(*this, true);  
    /*注:上面这句很关键,它关系到下面的if是否执行,也就是是否读输入流。这句从
 
语法上看,是 
    sentry是一个class, _Ok是sentry类的一个const对象,构造这个对象时需要传入两个
 
参数 
    第一个是流对象自身的引用,第二个表示对空白字符(如空格、制表符)的处理方式
 
,为true时意味着不忽略空白字符,即一个字符一个字符的从输入流中提取。 
    */  
      
    if (_Ok && 0 < _Count)   
    /* 
 
************************************************************************** 
    * sentry类内部重载了一个类型转换运算符,它把sentry类的实例转换成了一个bool
 
表达式。 
    * 这个表达式返回sentry类的私有成员_Ok的值。 
    bool sentry::operator bool() const 
    * { // test if _Ipfx succeeded 
    *       return (_Ok); 
    *   } 
    * _Ok这个成员的值由sentry类的构造函数 
    * 在初始化时设置,设置的过程比较麻烦,这里不做赘述(其实我也没看十分明白)。 
    * 但可以肯定的是,当输入流的状态是正常时,这个成员的值也是true, 
    * 反之,则是false。  
    *  
    * _Count是调用者传入的第二个参数,这里用做循环计数器的初值,以后每读一个字
 
符, 
    * _Count的值会减一。 
    
 
****************************************************************************
 
**/  
    {  
    // state okay, use facet to extract   
    int_type _Metadelim = _Traits::to_int_type(_Delim);   
    int_type _Meta = _Myios::rdbuf()->sgetc();//从输入流读一个字符   
    for (; ; _Meta = _Myios::rdbuf()->snextc()) //snextc()从输入流中读取下一
 
个字符  
        if (_Traits::eq_int_type(_Traits::eof(), _Meta))   
              {// end of file, quit   
                _State |= ios_base::eofbit;   
                break;   
               }//注:遇到文件尾,getline结束   
        else if (_Meta == _Metadelim) {  
             // got a delimiter, discard it and quit   
            ++_Chcount;    //读取字符数+1  
            _Myios::rdbuf()->sbumpc();  
            /*注:上面这句把结束符读掉了,如果不指定结束符,那就是把'\n'读掉了
 
。  
            但回车符本身并没有拷贝到缓冲区中, 
            这样下次的读操作将从回车符后面的第一个字符开始, 
            */  
            break;   
        }/* 注:遇到结束符,getline结束,注意这里的顺序,它是先判断是否遇到结束
 
符,后判断是否读入了指定个数的。 */  
        else if (--_Count <= 0)   
        {// buffer full, quit   
            _State |= ios_base::failbit;   
            break;   
        }  
        //注:读到了指定个数,执行到这里已经隐含了在指定个数的最后一位仍然不是
 
结束符,  
        //因此该部分将输入流状态置为了错误。  
        //这直接导致了接下来的getline(或者get)以及>>运算符等读操作都不能正确执
 
行)   
        else {  
            // got a character, add it to string   
            ++_Chcount;  //读取字符数加1  
            *_Str++ = _Traits::to_char_type(_Meta);   
        }//注:这一分支将读取到的单个字符拷贝到缓冲区中  
    }   
    *_Str = _Elem();  //  
    /* add terminating null character /*注:前面这句为字符串加入了终止符'\0' 
    因为_Elem()构造了一个ascii码为0的字符对象*/  
    _Myios::setstate(_Chcount == 0 ? _State | ios_base::failbit : _State);  
    /*注:如果没有读入任何字符,要保持执行这一次getline之前的输入流状态, 
    否则根据这一次getline执行的情况,设置输入流为相应状态。 */  
    return (*this);   //返回输入流对象本身  
}   

getline函数彻底说明的更多相关文章

  1. getline()函数

    这是一篇关于getline()函数的博客,以总结对输入输出流的掌握,不再在这些问题上栽跟头~ -------------------------- 1.首先我们知道,getline()函数的基本作用, ...

  2. C/C++中的getline函数总结:

    来自:http://www.cnblogs.com/xFreedom/archive/2011/05/16/2048037.html C/C++中的getline函数总结 getline函数是一个比较 ...

  3. C++: getline函数

    转自http://blog.sina.com.cn/s/blog_60263c1c0101ck25.html 学习C++的同学可能都会遇到一个getline()函数,譬如在C++premer中,标准s ...

  4. C++学习46 getline()函数读入一行字符 一些与输入有关的istream类成员函数

    getline函数的作用是从输入流中读取一行字符,其用法与带3个参数的get函数类似.即    cin.getline(字符数组(或字符指针), 字符个数n, 终止标志字符) [例13.7] 用get ...

  5. c程序设计语言_习题1-16_自己编写getline()函数,接收整行字符串,并完整输出

    Revise the main routine of the longest-line program so it will correctly print the length of arbitra ...

  6. Linux下的getline函数

    最近在做国嵌的mp3项目,在mp3主控程序中用到了这个函数,挺好使的,在这里记录一下.注意是linux下的,不是C++中的. 函数原型 ssize_t getline(char **lineptr, ...

  7. C++中getline函数的使用

    代码: #include <iostream> #include <cstdio> using namespace std; int main(){ char* s; s = ...

  8. getline函数

    在我的印象中,getline函数常常出如今自己的视野里,模糊地记得它常常常使用来读取字符串 .可是又对它的參数不是非常了解,今天又用到了getline函数,如今来细细地总结一下: 首先要明确设计get ...

  9. getline函数(精华版)

    在我的印象中,getline函数经常出现在自己的视野里,模糊地记得它经常用来读取字符串   .但是又对它的参数不是很了解,今天又用到了getline函数,现在来细细地总结一下:   首先要明白设计ge ...

随机推荐

  1. search 搜索

    hosts文件路径 C:/WINDOWS/system32/drivers/etc/hosts host tnsnames.ora文件路径 C:/oraclexe/app/oracle/product ...

  2. php 快速排序

    快速排序是以其中一个数为比较标准,其他比较的数分块处理,应用递归按相同想法处理数据 比如:4 3 6 2 1 7 8 以4为比较对象 排序为 3 2 1 6 7 8 左边为 3 2 1 右边 为 6 ...

  3. Struts——(四)异常处理机制

    在通常的情况下,我们得到异常以后,需要将页面导航到一个错误提示的页面,提示错误信息.利用Stuts我们可以采用两种方式处理异常: 1.编程式异常处理 即我们在Action中调用业务逻辑层对象的方法时, ...

  4. hdu 1849(Rabbit and Grass) 尼姆博弈

    Rabbit and Grass Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  5. h5 摄像头处理 在线视频

    http://www.360doc.com/content/08/0812/03/72059_1533104.shtml http://html5online.com.cn/articles/2012 ...

  6. nginx 隐藏版本信息

    隐藏nginx头部  修改后的src/core/nginx.h ,代码如下:   /*  * Copyright (C) Igor Sysoev  * Copyright (C) Nginx, Inc ...

  7. Create side-by-side stereo pairs in the Unity game engine

    Create side-by-side stereo pairs in the Unity game engine Paul BourkeDecember 2008 Sample Island pro ...

  8. 收缩SQL Server 数据库的几种方法

    方法一: Use 数据库名 Select NAME,size From sys.database_files ALTER DATABASE 数据库名 SET RECOVERY SIMPLE WITH ...

  9. windows 8.1 下蓝屏报错:SYSTEM_SERVICE_EXCEPTION(NETIO.SYS)的解决办法

         大概2周前,电脑突然蓝屏了,我上网查了一下解决办法,因为大部分内容是英文的,所以我只大概看了下,看到这个问题好像是由于软件冲突造成的,于是就把小红伞去掉了,而那天电脑也真的没有再蓝屏(之前大 ...

  10. 近期微博吐槽言论存档,涉及“性能优化”、C++陋习等

    写C++程序的几个陋习:class 名以大写 C 开头,例如 CDate:成员变量以 m_ 开头:变量采用匈牙利命名法:不知道何时禁用 copy-ctor/assign operator.前三个可能是 ...