getline的实现(istream& is,string& str)

时间:2012-09-04 17:29:53

标签: c++ string

我的问题很简单,getline(istream,string)是如何实现的? 你如何解决像getline(char * s,streamsize n)这样固定大小的char数组的问题? 他们是否使用临时缓冲区和许多调用新char [length]或其他整齐的结构?

3 个答案:

答案 0 :(得分:7)

getline(istream&, string&)以读取行的方式实现。它没有明确的实施;每个图书馆可能彼此不同。

可能的实施:

istream& getline(istream& stream, string& str)
{
  char ch;
  str.clear();
  while (stream.get(ch) && ch != '\n')
    str.push_back(ch);
  return stream;
}

答案 1 :(得分:5)

@SethCarnegie是对的:可以实现多个实现。 C ++标准没有说明应该使用哪个。

然而,问题仍然很有趣。这是一个典型的计算机科学问题。当一个人事先不知道要分配多少内存时,在哪里以及如何分配内存?

  1. 一种解决方案是将字符串的字符记录为单个字符的链接列表。这既不是内存效率也不是快速,但它有效,稳健,编程相对简单。但是,标准库不太可能以这种方式实现。

  2. 第二种解决方案是分配一些固定长度的缓冲区,例如128个字符。当缓冲区溢出时,您分配一个双倍长度,256个字符的新缓冲区,然后将旧字符复制到新存储区,然后释放旧缓冲区。当新缓冲区溢出时,再次分配一个双倍长度的更新缓冲区,512个字符,然后重复该过程;等等。

  3. 第三种解决方案结合了前两种。保持字符数组的链接列表。列表的前两个成员(例如)每个成员128个字符。第三个存储256.第四个存储512,依此类推。这需要比其他编程更多的编程,但根据应用程序的不同,可能更好。

  4. 可能的实施清单继续。

    关于标准库实现,@ SteveJessop补充说“由于operator[]对字符串的复杂性要求,”[a]标准库的字符串不允许实现为(1)。在C ++中11由于字符串的连续性要求,不允许将其作为(3)实现.C ++委员会表示相信在添加邻接要求时没有活跃的C ++实现(3)。当然,{{ 1}}可以在将字符全部添加到字符串之前用字符暂时执行它喜欢的操作,但标准确实说明了字符串可以做什么。“

    添加是相关的,因为尽管getline可以以多种方式临时存储其数据,但如果数据的最终目标是字符串,这可能与getline的实现相关。 @SteveJessop进一步补充说,“对于字符串本身来说,除了可以选择自己的扩展速率之外,它们几乎都需要实现;只要它们乘以某个常量,它们就不必每次都加倍。”

答案 2 :(得分:0)

正如@ 3bdalla所说,thb的实现不能作为gnu的实现。因此,我编写了自己的实现,其工作方式类似于gnu的实现。我不知道此变体中会出现什么错误,因此需要对其进行测试。 我对getline的实现:

std::istream& getline(std::istream& is, std::string& s, char delim = '\n'){
    s.clear();
    char c;
    std::string temp;
    if(is.get(c)){
        temp.push_back(c);
        while((is.get(c)) && (c != delim))
            temp.push_back(c);
        if(!is.bad())
            s = temp;
        if(!is.bad() && is.eof())
            is.clear(std::ios_base::eofbit);
    }
    return is;
}