Обработка файла в C ++, is_open возвращает плохой - PullRequest
0 голосов
/ 28 января 2012

Если я включу тест if в мой код, возвращается сообщение об ошибке, и я не уверен почемуи когда он не используется, моя программа get застревает в цикле, где она никогда не достигает конца файлаЯ не понимаю, что происходит не так.

int countlines()
{
    fstream myfile;
    myfile.open("questions.txt", ios::in);
    string contents;
    int linenumber = 0;

    //if (myfile.is_open())  
    // {
    while (!myfile.eof())  
    {
        getline( myfile, contents );
        if (contents != "")
        {
            linenumber++;
        }
    }
    cout << "there are " << linenumber << " lines.\n";
    //}else {cout<<"Unable to get file.\n";}

    myfile.close();
    return(linenumber);
}

Ответы [ 4 ]

3 голосов
/ 28 января 2012

Что происходит, так это то, что ваш файл не открывается. Вот почему is_open терпит неудачу.

Затем, когда вы закомментируете проверку, вы нарушаете свой цикл, потому что вы выполняете итерацию неправильно (см. Мой комментарий) и не обнаруживает сбои потока (.eof() никогда не будет никогда будет true в этом потоке).

Убедитесь, что файл находится в нужном месте и доступен.

2 голосов
/ 28 января 2012

Правильная идиома для чтения файла построчно в C ++ использует такой цикл:

for (std::string line; std::getline(file,line);)
{
    // process line.
}

Вставка этого в ваш пример (+ исправление отступов и имен переменных) дает что-то вроде этого:

int countlines(const std::string& path)
{
    // Open the file.
    std::ifstream file(path.c_str());
    if (!file.is_open()) {
        return -1; // or better, throw exception.
    }

    // Count the lines.
    int count = 0;
    for (std::string line; std::getline(file,line);)
    {
        if (!line.empty()) {
            ++count;
        }
    }

    return count;
}

Обратите внимание: если вы не собираетесь обрабатывать содержимое строки, вы можете пропустить их обработку, используя std::streambuf_iterator, что может сделать ваш код похожим на:

int countlines(const std::string& path)
{
    // Open the file.
    std::ifstream file(path.c_str());
    if (!file.is_open()) {
        return -1; // or better, throw exception.
    }

    // Refer to the beginning and end of the file with
    // iterators that process the file character by character.
    std::istreambuf_iterator<char> current(file);
    const std::istreambuf_iterator<char> end;

    // Count the number of newline characters.
    return std::count(current, end, '\n');
}

Вторая версия полностью обойдет копирование содержимого файла и позволит избежать выделения больших кусков памяти для длинных строк.

2 голосов
/ 28 января 2012

При использовании std::istream и std::ostream (чьи реализации std::fstream) рекомендуется использовать поток напрямую в контексте bool вместо вызова функции eof(), поскольку он возвращает true только тогда, когда вам удалосьчитать до последнего байта файла.Если до этого произошла какая-либо ошибка, функция все равно вернет true.

Итак, вы должны были написать свой код как:

int countlines() {
    ifstream myfile;
    int linenumber = 0;
    string linecontent;
    myfile.open("question.txt", ios::in);
    while (getline(myfile, linecontent)) {
        if (!linecontent.empty()) {
            ++linenumber;
        }
    }
    return linenumber;
}
0 голосов
/ 28 января 2012

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

int countlines()
{
    ifstream myfile;
    myfile.open("questions.txt");
    string contents;
    int linenumber = 0;

    if (myfile.is_open())  
    {
        while (getline(myfile, contents))  
        {
            if (contents != "")
                linenumber++;
        }
        cout << "there are " << linenumber << " lines." << endl;        
        myfile.close();
    }
    else
        cout << "Unable to get file (reason: " << strerror(errno) << ")." << endl;

    return linenumber;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...