Реализация getline (istream & amp; is, string & amp; str)

Мой вопрос очень прост, как реализован getline (istream, string)?
Как вы можете решить проблему наличия массивов символов фиксированного размера, как с getline (char * s, streamsize n)?
Используют ли они временные буферы и много вызовов нового символа [длины] или другой аккуратной структуры?

6

Решение

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;
}
7

Другие решения

@SethCarnegie прав: возможно более одной реализации. Стандарт C ++ не говорит, что следует использовать.

Однако вопрос все еще интересен. Это классическая компьютерная проблема. Где и как можно выделить память, если заранее не знаешь, сколько памяти выделить?

  1. Одним из решений является запись символов строки в виде связанный список отдельных персонажей. Это не является ни эффективным с точки зрения памяти, ни быстрым, но он работает, надежен и относительно прост в программировании. Однако стандартная библиотека вряд ли будет реализована таким образом.

  2. Второе решение состоит в том, чтобы выделить буфер некоторой фиксированной длины, такой как 128 символов. Когда буфер переполняется, вы выделяете новый буфер двойной длины, 256 символов, затем копируете старые символы в новое хранилище, а затем освобождаете старый. Когда новый буфер переполняется, вы снова выделяете еще более новый буфер двойной длины, 512 символов, а затем повторяете процесс; и так далее.

  3. Третье решение объединяет первые два. Связанный список массивов символов поддерживается. Первые два члена списка хранят (скажем) 128 символов каждый. Третий хранит 256. Четвертый хранит 512 и так далее. Это требует больше программирования, чем другие, но может быть предпочтительнее любого из них, в зависимости от приложения.

И список возможных реализаций продолжается.

Что касается реализаций стандартной библиотеки, @SteveJessop добавляет, что «строка стандартной библиотеки [a] не может быть реализована как (1) из-за требования сложности operator[] для струнных. В C ++ 11 также не разрешено реализовывать как (3) из-за требования смежности строк. Комитет C ++ выразил убеждение, что ни одна активная реализация C ++ не сделала (3) в то время, когда они добавили требование смежности. Конечно, getline может временно делать с символами то, что ему нравится, прежде чем добавлять их в строку, но стандарт действительно многое говорит о том, что может делать строка. «

Дополнение актуально, потому что, хотя getline может временно хранить свои данные любым из нескольких способов, если конечной целью данных является строка, это может иметь отношение к getlineРеализация. @SteveJessop далее добавляет: «Для самой строки реализации в значительной степени требуется (2), за исключением того, что они могут выбирать собственную скорость расширения; им не нужно удваиваться каждый раз, пока они умножаются на некоторую константу».

5