Парсинг строк при чтении больших файлов c++

169
17 февраля 2019, 02:10

В процессе поиска наиболее быстрого алгоритма чтения файла и парсинга данных, возникла ошибка. Первоначально тип читаемых строк в файле (а именно интерес представляет последнее число типа float, а остальное мусор): 12242BENZ H6 24 11.060 8.703 4.112

Поскольку, к примеру на хабре представлены разные методы работы с iostream, в силу моей низкой квалификации в c++ я решил не заморачиваться по поводу использования Boost::Spirit::Qi (хотя, если есть умельцы, которые могут подсказать путь для создания через Boost::Spirit::Qi парсера для float, то буду признателен) и использовать довольно простенький алгоритм:

ifstream fid("Benzene_Simu1_0_35ns.gro");
if (!fid) throw exception("Bad opening");   
std::ios::sync_with_stdio(false);
char buffer[80];
char * test;
//vector <float> coordinates(3);
float coordinates = 0.0;
vector <float> coordinate;
while (true)
{
    if (fid.eof()) break;
    fid.ignore(std::numeric_limits<size_t>::max(), '\n');
    fid.ignore(std::numeric_limits<size_t>::max(), '\n');
    for (int i = 0; i < 120; i++) {
        fid.getline(buffer, sizeof(buffer));
        test = strrchr(buffer, ' '); //take pointer on last float in string
        std::advance(test, 1);
        sscanf(test, "%f", &coordinates); //select z_axis value
        coordinate.push_back(coordinates);
    }
    fid.ignore(std::numeric_limits<size_t>::max(), '\n');
}
cout << coordinate[sizeof(coordinate) - 1] << endl;
cout << clock()/1000 << endl;
_getch();

Так вот, в результате работы такого алгоритма в строке кода

sscanf(test, "%f", &coordinates); //select z_axis value

появляется ошибка

Unhandled exception at 0x5B031BCC (ucrtbased.dll) in ConsoleApplication1.exe: 0xC0000005: Access violation reading location 0x00000001. occurred

Какие комментарии и замечания будут по поводу данной ситуации и кода?

Answer 1

Помимо всего прочего у вас куча игнорирования строк (т.е. их чтения в никуда) + неверная проверка конца файла. Так что вопрос - вы точно читаете строки?

Вы же не проверяете, что строка считана... Может, там какая-то ерунда, в буфере?

И, кстати, ваш advance(test,1) совершенно ни к чему. В отличие от проверки, не равен ли test == nullptr...

Answer 2

Если пробел не найден, то strrchr(buffer, ' '); возвратит нулевой указатель. Соответственно надо 1) проверять что у вас строка прочиталась, 2) проверять что пробел найден.

READ ALSO
Задача с страницами книги

Задача с страницами книги

Есть задача, я ее правильно решил, но на одном из тестов выдает "Time limit error"Перепробовал самые различные варианты решения этой задачи, в том...

174
Превышен лимит выполнения

Превышен лимит выполнения

И так я пишу програмулину, которую будет проверять компуктер, и проблема в том что на моей локальной машине все работает в штатном режиме,...

177
Кириллица в CLion

Кириллица в CLion

Написал небольшое приложение

195
Как подставить в FindFirstFile букву? [закрыт]

Как подставить в FindFirstFile букву? [закрыт]

В примере указано что диск С но нужно менять в индивидуальном порядке как можно это сделать чтоб указывало?

193