Ошибка сегментации на getline при разборе файла - PullRequest
0 голосов
/ 21 апреля 2020

Я делаю очень простой анализатор файлов в стиле CSV. Компиляция работает без сбоев, и когда я ее запускаю, у меня возникает ошибка (сбрасывается ядро). Единственная напечатанная строка - это надпись «Готово», указывающая, что файл успешно открыт. Поэтому я предполагаю, что Сегфоут произошел во время while(getline(myfile, line)).

Вот мой код (parser.cpp):

#include "parser.h"

vector<string> str_explode(string const & s, char delim)
{
    vector<string> result;
    istringstream iss(s);

    for (string token; getline(iss, token, delim); )
    {
        result.push_back(move(token));
    }
    return result;
}

vector<vector<string>> getTokensFromFile(string fileName)
{
    bool verbose = true;
    if(verbose)
        cout << "Entering getTokensFromFile(" << fileName << ")" << endl ;
    /* declaring what we'll need :
     * string line -> the line beeing parsed
     * ifstream myfile -> the file that name has been given as parameter
     * vector <vector <string> > tokens -> the return value
     * 
     * Putting all line into tokens
     */

    string line;
    ifstream myfile(fileName);
    vector< vector<string> > tokens;
    if(verbose)
        cout << "Opening file " << fileName << " ... ";
    if (myfile.is_open())
    {
        if(verbose)
            cout << "Done !" << endl;
        while (getline (myfile,line))
        {
            if(verbose)
                cout << "Parsing line '" << line << "'. ";
            // If line is blank or start with # (comment)
            // then we don't parse it
            if((line.length() == 0) || (line.at(0) == '#'))
            {
                if(verbose)
                    cout << "Empty or comment, passing.";
                continue;
            }
            else
            {
                vector <string> tmptokens;
                if(verbose)
                    cout << "Adding token " << tmptokens[0] << " and its values.";
                tokens.push_back(tmptokens);
            }
            cout << endl;
        }
    }
    else
    {
        cout << "Unable to open file " << fileName << endl;
        throw exception();
    }
    if(verbose)
        cout << "Exiting getTokensFromFile(" << fileName << ")" << endl;
    return tokens;
}

main.cpp

#include "parser.h"

int main()
{
    getTokensFromFile("testfile.csv");
    return 0;
}

И my testfile.csv

version;1.3
###### SPECIE ######
SpecieID;Value1
VariantID;Value2
####################

##### IDENTITY #####
Name;Value3
DOName;Value4
####################

Все файлы находятся в одной папке.

Есть ли у вас какие-либо подсказки, почему у меня возникает этот segfault?

Спасибо

1 Ответ

2 голосов
/ 21 апреля 2020

Вот одна очевидная ошибка, когда вы обращаетесь к элементу вектора за пределами. Доступ к элементу вне пределов является неопределенным поведением.

   else
   {
       vector <string> tmptokens;
       if(verbose)
           cout << "Adding token " << tmptokens[0] << " and its values.";
       tokens.push_back(tmptokens);
   }

Поскольку tmptokens пусто, tmptokens[0] отсутствует.

Если вектор пуст, вы могли бы сделать это:

   else
   {
       if(verbose)
           cout << "Adding new token and its values.";
       tokens.push_back({});
   }

Нет необходимости вручную создавать пустой вектор, начиная с C ++ 11.

...