Пользовательский конечный итератор istream

#c #c 11

#c #c 11

Вопрос:

Я хочу прочитать одну строку текста из istream и разбить ее на слова. Мой текущий код

 vector<string>((istream_iterator<string>(f)),
                                istream_iterator<string>());
  

где f — ifstream объект. Однако при этом выполняется чтение до конца файла, и я хочу остановить его чтение, когда он достигает новой строки. Есть ли какой-нибудь способ сделать что-то вроде istream_iterator<string>("n") , чтобы векторный конструктор перестал выполнять возврат при достижении новой строки?

Комментарии:

1. Чтобы прочитать lime за раз, используйте std::getline() .

Ответ №1:

Используется std::getline() для чтения одной строки, а затем используется std::istringstream для чтения слов из этой строки, например:

 std::string line;
std::getline(f, line);
std::istringstream iss(line);
std::vector<std::string> words(
    std::istream_iterator<std::string>(iss),
    std::istream_iterator<std::string>()
);
  

Ответ №2:

Используйте std::getline для чтения каждой строки и отправки их в ваш контейнер результатов

 std::vector<std::string> lines;
for (std::string line; std::getline(f, line); lines.push_back(line));
  

Редактировать: Реми Лебо уже ответил на вопрос OP, я хочу уточнить свой код:

Обычно для чтения строк в файле мы бы написали что-то вроде

 while (f.good())
{
    std::string line;
    std::getline(f, line);
    lines.push_back(line);
}
  

Поскольку std::istream может быть преобразован в логическое значение, мы можем переписать его как:

 while (f)
{
    std::string line;
    std::getline(f, line);
    lines.push_back(line);
}
  

И поскольку std::getline возвращает сам входной поток, мы можем использовать его в качестве условия цикла:

 std::string line;
while (std::getline(f, line))
{
    lines.push_back(line);
} // `line` still can be used after this line, outside its scope
  

Но мы должны вывести временную переменную line за пределы ее области видимости. Чтобы избежать этого, мы используем for вместо while цикла и объявляем line внутри for цикла:

 for (std::string line; std::getline(f, line); )
{
    lines.push_back(line);
}
  

Наконец, поскольку тело цикла содержит только 1 строку, мы также можем поместить его внутрь for цикла:

 for (std::string line; std::getline(f, line); lines.push_back(line));
  

Комментарии:

1. Вероятно, будет хорошей идеей объяснить немного больше о том, что делает этот несколько плотный код.

2. Уточнение: я хочу прочитать только одну строку и разбить эту строку на вектор word