Это правильный способ открыть файл для ввода? - PullRequest
0 голосов
/ 25 сентября 2011

Это правильный способ открыть файл для ввода?

void BinaryTree::read(char * path, int line_number)
{
    ifstream * file(path); //error: cannot convert ‘char*’ to ‘std::ifstream*’ in initialization
    file->seekg(0, std::ios::beg);
    int length = file.tellg();
    char * buffer = new char[length];
    file->getline(buffer, line_number);
    printf("%d", length);
    file->close();

}

Наверное, нет, потому что компилятор не примет массив char или std::string для конструктора ifstream, но когда я читаю документацию , я вижу string s и / или char массивы передаются конструкторам ifstream.

Что-то не так с моим компилятором или я просто использую неверный тип в своем параметре?

Ответы [ 5 ]

2 голосов
/ 25 сентября 2011

Не используйте указатель. Здесь не нужно.

Попробуйте это:

ifstream file(path);

, а затем использовать его как:

//...
file.getline(buffer, line_number);//file->getline(buffer, line_number);
//...
1 голос
/ 25 сентября 2011
ifstream * file(path); //error: cannot convert ‘char*’ to ‘std::ifstream*’ in initialization

Проблема в том, что конструкция объекта не подходит. Вы, вероятно, пытаетесь сделать следующее (или нечто подобное), действительно передав массив char в конструктор объекта ifstream:

ifstream file(path);

Однако введение звездочки здесь меняет весь смысл. Вы создаете указатель на объект ifstream, но не сам объект ifstream. А для создания указателя вам понадобится другой указатель на объект ifstream (то есть указатель того же типа).

ifstream file(path);
ifstream * ptr( &path );

Это не то, что вы намеревались сделать, в любом случае, вы, вероятно, хотели создать ifstream объект, на который ссылается указатель:

ifstream * file = new ifstream( path );
//... more things...
file->close();

Но помните, что объект должен освобождаться, когда он больше не нужен. Объекты, на которые ссылаются указатели, не освобождаются автоматически, как это происходит с обычными (объекты в стеке) объектами.

ifstream * file = new ifstream( path );
//... more things...
file->close();
delete file;

Надеюсь, это поможет.

0 голосов
/ 25 сентября 2011

У вас больше проблем, чем указано выше:

  • вы по-разному используете файл в качестве указателя, а также объект (file-> seekg (...) и file.tellg ())
  • вы занимаетесь позицией с помощью Tellg после перемещения в начало файла с помощью seekg, а затем используете эту позицию, чтобы указать размер буфера.Это даст вам пустой буфер (я думаю, в лучшем случае указатель на ноль байтов).
  • тогда вы вызываете getline с параметром line_number, переданным в качестве аргумента.Это приведет к тому, что getline будет читать не более байтов line_number, но вы выделили только байты длины (что, как мы видели выше, равно нулю).Я предполагаю, что вы хотите прочитать строку line_number'th, но это требует немного больше работы - вы должны подсчитывать количество строк line_number до тех пор, пока не достигнете правильной строки.файл каждый раз, когда вы получаете следующую строку - вы, возможно, захотите переосмыслить свой интерфейс в целом.

извинения, если я здесь упустил пункт

0 голосов
/ 25 сентября 2011

Пара вещей, которые я бы изменил:

void BinaryTree::read(char * path, int line_number)
{
    // Use an object not a pointer.
    ifstream*        file(path);

    // When you open it by default it is at the beginning.
    // So we can remove it.
    file->seekg(0, std::ios::beg);

    // Doing manually memory line management.
    // Is going to make things harder. Use the std::string
    int length = file.tellg();
    char * buffer = new char[length];
    file.getline(buffer, line_number);

    // Printing the line use the C++ streams.
    printf("%d", length);

    // DO NOT manually close() the file.
    // When the object goes out of scope it will be closed automatically
    // http://codereview.stackexchange.com/q/540/507
    file->close();

}  // file closed here automatically by the iostream::close()

Упрощено здесь:

void BinaryTree::read(char * path, int line_number)
{
    ifstream        file(path);

    std::string   line;
    std::getline(file, line);

    std::cout << line.size() << "\n";
} 
0 голосов
/ 25 сентября 2011

Указатель не нужен, как сказал @Nawaz:

ifstream *file(path);

Потенциальная утечка памяти:

char *buffer = new char[length];

Вы должны delete[] потом:

delete[] buffer;

... Но , использовать намного проще std::string:

std::string buffer;

Окончательный код:

std::string BinaryTree::read(std::string path, int line_number)
{
    std::string buf;
    ifstream file(path.c_str());

    if(file.is_open())
    {
        // file.seekg(0, std::ios::beg); // @Tux-D says it's unnecessary.
        file.getline(buf, line_number);
        file.close();
    }

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