这是打开文件输入的正确方法吗?

时间:2011-09-25 18:53:10

标签: c++ file-io

这是打开文件进行输入的正确方法吗?

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,但是当我读到documentation时,我看到string和/或char数组传递给ifstream构造函数。

我的编译器出了什么问题,或者我在参数中使用了错误的类型?

5 个答案:

答案 0 :(得分:2)

不要使用指针。这里不需要它。

试试这个:

ifstream file(path);

然后将其用作:

//...
file.getline(buffer, line_number);//file->getline(buffer, line_number);
//...

答案 1 :(得分:1)

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;

希望这有帮助。

答案 2 :(得分:0)

没有指针需要,因为@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;
}

答案 3 :(得分:0)

我会改变一些事情:

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";
} 

答案 4 :(得分:0)

你遇到的问题多于上面提到的问题:

  • 你正在使用各种文件作为指针和对象(file-&gt; seekg(...)和file.tellg())
  • 在使用seekg移动到文件的开头后使用tellg获取位置,然后使用该位置为您提供缓冲区的大小。这将为您提供一个空缓冲区(我认为最好是指向零字节的指针)。
  • 然后使用作为参数传递的line_number参数调用getline。这将导致getline最多读取line_number字节,但是你只分配了长度字节(正如我们在上面看到的那样为零)。我想你想要阅读line_number'行,但这需要更多的工作 - 你必须计算line_number换行符,直到你到达正确的行。
  • 更常见的是,每次下一行时都要打开和关闭文件 - 您可能希望重新考虑整个界面。
如果我错过了这一点,

道歉