0

我想打开一个随机.txt文件并将数据放入一些字符串中。如果我将路径写入代码,它会起作用。

我不明白为什么这不起作用。

#include <iostream>
#include <fstream>

using namespace std;

int main()
{
    string file;

    ifstream filein(file.c_str());

    cout << "Insert Path" << endl;
    cin >> file;

    cout << file << endl;

    filein.open(file.c_str(), ios::in);

    for (string line; getline(filein, line);) {
        cout << line << endl;
    }

    return 0;
}
4

3 回答 3

2

您的文件名字符串为空,因为std::string默认为空。

您将一个空字符串(或 nul 字符串)传递给ifstream构造函数,这充其量是未定义的行为。

于 2017-01-06T19:37:08.140 回答
0

尝试像这样编写代码:

#include <iostream>
#include <fstream>

int main()
{
    std::string file;

    std::cout << "Insert Path" << std::endl;
    std::getline(std::cin, file);

    std::cout << file << std::endl;

    std::ifstream filein(file);

    for (std::string line; std::getline(filein, line); )
    {
        std::cout << line << std::endl;
    }

    return 0;
}

值得注意的编辑包括:

  • 我们现在ifstream只在需要时构建对象,在file存储了数据之后,这意味着不再有未定义的行为,并且我们只在知道路径是什么之后才尝试打开文件。
  • 我们在存储到时检索一整行file,而不是仅检索第一个单词,如果您的路径包含任何空格,这一点至关重要。
  • 我们只是file直接使用字符串。没有必要打电话c_str()
  • 我们不再使用using namespace std;. 为什么这是不好的做法有很多很多原因。

编辑:

如果你有一个兼容 C++17 的编译器,我建议你编写如下代码:

#include <iostream>
#include <fstream>
//You may need to write #include <experimental/filesystem>
#include <filesystem>
#include <string>

int main()
{
    std::string input_line;

    std::cout << "Insert Path" << std::endl;
    std::getline(std::cin, input_line);

    //You may need to write std::experimental::filesystem
    std::filesystem::path file_path{input_line};
    //This will print the "absolute path", which is more valuable for debugging purposes
    std::cout << std::filesystem::absolute(file_path) << std::endl;

    std::ifstream filein(file_path);

    for (std::string line; std::getline(filein, line); )
    {
        cout << line << endl;
    }

    return 0;
}

显式使用path对象将使您的代码更具可读性并使错误更加明确,并授予您访问原本无法访问的行为的权限。

于 2017-01-06T19:37:21.930 回答
0

首先你要打开什么?只要你的字符串不包含任何东西?

第二,即使字符串包含有效路径并且第一次打开成功但第二次将失败,只要您在多个文件上使用相同的文件流而不清除其缓冲区并关闭前一个文件:

string file "C:\\MyProject\\data.txt"; // let's say a valid path

ifstream filein(file.c_str());

if(filein.fail()) // the condition fails as long as the opening was successfull
    cout << "failed to open file!" << endl;

cout << "Insert Path" << endl;
cin >> file; // let's say the user enters a valid path again: "C:\\MyProject\\test.txt"

cout << file << endl;

filein.open(file.c_str(), ios::in); // fail to correct it:

filein.close();
filein.clear(); // very important

filein.open(file.c_str(), ios::in); // now it's ok!

for (string line; getline(filein, line);) {
    cout << line << endl;
}
于 2017-01-06T22:09:29.683 回答