ifstream + 打开随机 TXT 文件 (c_str)
ifstream + opening random txt file (c_str)
我想打开一个随机的.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;
}
您的文件名字符串为空,因为std::string
默认为空。
您正在将空字符串(或 nul 字符串)传递给 ifstream
构造函数,这充其量是未定义的行为。
尝试像这样编写代码:
#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
对象将使代码更具可读性,使错误更加明确,并授予您访问原本无法访问的行为的权限。
首先你要
打开什么? 只要你的字符串不包含任何东西??
第二个,即使字符串包含有效路径并且第一次打开成功,但在第二个中,只要您在多个文件上使用相同的文件流而不清除其缓冲区并关闭前一个文件,就会失败:
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;
}
相关文章:
- .cpp和.h文件中的模板专用化声明
- 为什么两个不同的未命名名称空间可以共存于一个cpp文件中
- 文本文件中的单词链表
- CMake-按正确顺序将项目与C运行时对象文件链接
- 使用新行和不使用新行读取文件
- 在C++程序中输入的文本文件将不起作用,除非文本被复制和粘贴
- 挂起和取消挂起一个文件DLL
- 如何确定我已使用非编码文件到达 EOF?
- 命名空间中具有.h和.cpp文件的类
- 如何使用ndk-build.cmd构建Android.so文件
- 从包含m行的文件中提取n行,必要时(惰性地)重复该文件
- 读取文件并输入到矢量中
- 在C++中查找文件
- c++库的公共头文件中应该包含什么
- 用c++从输入文件中读取另一行
- Cppcheck生成xml转储文件
- 读取文件的最后一行并输入到链接列表时出错
- 无法编译 rtmidi 测试 cmidiin.cpp 文件, 非法指令
- std::string 到 str::string.c_str() 与文件路径的转换中存在有趣的问题
- c++:以std::string (&str[0])作为缓冲区安全地读取文件