2014-11-17 3 views
3

https://stackoverflow.com/a/1120224/390066.Как использовать конструктор stringstream в getline?

Почему я не могу использовать

getline(stringstream(line),cell,','){} 

вместо

stringstream lineStream(line); 
getline(lineStream,cell,','){} 

?

обновление

я должен уточнить, что я хочу использовать GetLine внутри цикла.

Кроме того, я должен был также отметить, что мое первоначальное намерение состояло в том, чтобы прочитать файл по строкам с помощью getline и использовать строку из этой строки в новой линии getline, которая будет делить на ',', что более интуитивно понятное imo ,

Из того, что я понял до сих пор, getline не предназначен для этого, потому что он принимает неконстантный вход и дает токен const; поэтому getline не может быть слепо рекурсивно.

+0

getline изменит какой-то временный объект, который всегда будет неизменным. – NaCl

+0

Было бы важно сохранить значение во временной переменной ... – ravi

+1

Определить 'template T & stay (T && x) {return x; } 'и попробуйте:' std :: getline (stay (std :: istringstream (строка)), cell, ',') '. –

ответ

3

Как показано компанией @James Kanze, вы можете.

Вопрос в том, что вы действительно хотите?
Поток уничтожается в конце выражения, поэтому вы читаете только одну ячейку.

Если мы посмотрим на это в context of the original question:
т.е. Вы не можете использовать это в цикле:

std::string  line = /* Init */; 
std::stringstream lineStream(line); 

std::string cell; 
while(std::getline(lineStream, cell, ',')) 
{ 
    // Do stuff with cell. 
} 

Если вы поместите свой код в связи с этим он не будет работать, как ожидалось:

std::string cell; 
while(std::getline(std::istringstream(line).flush(), cell, ',')) 
{ 
    // Do stuff with cell. 
} 

Поскольку выражение внутри while() будет полностью оцениваться каждый раз. Таким образом, вы переходите в непрерывный цикл, непрерывно читающий первую ячейку.

+0

Он может захотеть. Если он использует 'getline', есть более эффективные и более естественные способы сделать это, используя' std :: find' или 'std :: find_if'; однако это может быть полезно для выбора начального численного значения. (В целом, как и вы, я настроен скептически. Обычно вы хотите проверить статус после извлечения. Но я уверен, что есть случаи.) –

+0

@JamesKanze: Есть более эффективные способы. Но для меня это очень естественно. Использование 'std :: find()' больше похоже на C и требует дополнительного вспомогательного кода для доступа к одной и той же точке. Таким образом, эту технику легко учить, поскольку все детали обрабатываются для вас, в то время как вы можете сосредоточиться на результатах. –

1

Вы можете, но это некрасиво:

std::getline(std::istringstream(line).flush(), cell, ','); 

Проблема заключается в том, что std::getline принимает неконстантную ссылку (которая логично, так как он собирается изменить поток), и вы не можете Initialize неконстантная ссылка с временным. Вы можете, однако, функции вызова на нем. std::istream::flush - это функция , которая возвращает неконстантную ссылку на поток, на который был вызван (и если этот поток является std::istringstream, он не делает что-нибудь еще).

FWIW: вы, вероятно, найти:

cell = std::string(line.cbegin(), std::find(line.cbegin(), line.cend(), ',')); 

немного более эффективным. И, по крайней мере, на мой взгляд, читать легче и поддерживать.