stream — C ++ Чтение многострочного файла со строками произвольной длины и форматом без использования строкового потока

У меня есть входной поток со следующими строками:

# <int> <int>
<some_data_type> <some_data_type> <some_data_type> ..... <some_data_type>
<some_data_type_1> <some_data_type_2> <some_data_type_3> <some_data_type_1> <some_data_type_2> <some_data_type_3> .... <some_data_type_1> <some_data_type_2> <some_data_type_3>

В приведенном выше потоке все три строки различны и должны быть проанализированы по-разному. В настоящее время я использую метод чтения следующим образом:

void reader( std::istream & is, DataStructure & d ){
std::string line;
getline(is,line);
std::stringstream s(line);
//parse line 1

getline(is,line);
std::stringstream line2(line);
//parse line 2

getline(is,line);
std::stringstream line3(line);
//parse line 3

}

Теперь идея не в том, чтобы использовать std::stringstream вообще, поскольку строка может быть произвольно большой, и мы не хотим загружать все в память дважды. Таким образом, было бы лучше, если бы можно было читать из входного потока непосредственно в заданную пользователем структуру данных d.

Идея состоит в том, чтобы использовать std::istream_iterator но, к сожалению, разные строки имеют разные потребности в разборе. Например, в последней строке три элемента из потока вместе составляют один элемент данных.

Единственная идея, которая кажется мне правдоподобной на данный момент, — это непосредственная обработка буфера потока. Было бы здорово, если бы кто-нибудь мог порекомендовать лучший способ сделать это.

НОТА: Не могу использовать третичную структуру данных, как std::stringstream, Важно читать из потока непосредственно в предоставленную пользователем структуру данных.

РЕДАКТИРОВАТЬ: Обратите внимание, что нам разрешено только один проход по файлу.

1

Решение

Теперь идея вовсе не в том, чтобы использовать std :: stringstream как строку
может быть сколь угодно большим, и мы не хотим загружать все в память
дважды. Так что было бы лучше, если бы можно было читать с
входной поток непосредственно в заданную пользователем структуру данных d.

Olaf объяснил оператор извлечения выше, но тогда у нас есть новое требование:

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

а также

(2) К сожалению, у меня нет никакого дискриминатора вне моих знаний о том, что каждый экземпляр данных
структура должна быть создана с информацией, хранящейся в трех
разные линии. Все три линии имеют разную длину и разные
элементы данных. Кроме того, я не могу изменить формат.

плюс

(3) Вся информация рассматривается как целое число без знака.

Теперь следующая проблема заключается в том, что мы не знаем, какова структура данных на самом деле, поэтому, учитывая то, что произошло до того, как она каким-то образом окажется динамичной. Поскольку мы можем обрабатывать данные как unsigned int, тогда мы можем использовать оператор извлечения, но читать в динамический член:

vector<unsigned int> myUInts;
...
inFile >> currentUInt;
myUInts.push_back(currentUInt);

Но тогда возникает вопрос, где остановиться. Это в конце первой строки, третьей? Если вам нужно прочитать произвольное количество целых чисел без знака, при этом проверяя новую строку, вам также потребуется обработать пробел:

inFile.unsetf(ios_base::skipws);

То, как вы на самом деле справляетесь с этим, выходит за рамки того, что я могу сказать сейчас, без каких-либо более четких требований. Но я думаю, это будет в форме:

 inFile >> myMember;
char next = infile.peek()
//skip whitespace and check for new line
//Repeat until data structure filled, and repeat for each data structure.
2

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

Тогда не используйте std::getline() совсем. Определите оператор istream для ваших типов и используйте их напрямую

std::istream &operator >>(std::istream &f, DataStructure &d)
{
f >> d.member1 >> d.member2 >> ...;
return f;
}

void reader(std::istream & is, DataStructure &d)
{
is >> d;
}

Там нет необходимости возиться с std::istream_iterator или непосредственно манипулируя потоковым буфером.

1

По вопросам рекламы [email protected]