Я прочитал файл ASCII с Fstream. Строка содержит не менее двух повторений следующего паттерна (и не более 128):
%d %llu %d %d %llu %d %d %llu
Для каждой строки мне нужен максимум третьего% d каждого шаблона в строке
Я не могу найти способ сделать это правильно с Sscanf.
myFstreams->getline (buffer, MAX_BUFF-1);
while( ... ){
sscanf (buffer," %*d %*llu %*d %d %*llu %*d %*d %*llu",&number);
if(number>max) max=number;
//modify buffer ???
}
любая помощь будет принята с благодарностью.
Как насчет чего-то в этом роде: (код не проверен)
#include <limits>
#include <sstream>
...
std::string line;
while(std::getline(input_stream,line))//delimit by /n
{
auto line_ss = std::stringstream(line);
std::string token;
int number = std::numeric_limits<int>::min();
int k=0;
while(std::getline(line_ss,token,' '))//delimit by space
{
if(k == 3) // 3rd number
{
int i3;
std::stringstream(token) >> i3;
number = std::max(number,i3)
}
k = k == 7 ? 0: k+1; //8 numbers in the set
}
}
Ваш подход выглядит хорошо, спасибо за использование %*
подавить назначение.
Вам нужно добавить код, чтобы проверить возвращаемое значение sscanf()
и зацикливаться до тех пор, пока не произойдет сбой (т.е. он не вернется 1
). В цикле поддерживайте максимум, сравнивая каждое преобразованное значение с наибольшим, которое вы когда-либо видели.
ОБНОВИТЬЯ понял, что не учел повторяющийся узор в одном и том же аспекте линии. D’о. Я думаю, что одним из решений было бы использовать %n
спецификатор в конце шаблона. Это напишет (через и int *
аргумент) количество обработанных символов и, таким образом, позволяет сделать шаг вперед в строке для следующего вызова sscanf()
,
Есть один «секретный» тип, используемый scanf
и не printf
Вот почему это часто забывают: %n
while( ... )
{
//%n gives number of bytes read so far
int bytesRead =0;
sscanf (buffer," %*d %*llu %*d %d %*llu %*d %*d %*llu%n",&number, &bytesRead);
if(number>max)
max=number;
buffer +=bytesRead;//be cautious here if using UTF-8 or other MCBS
}