TL; DR文件名存储为数组中的字符串(使用new) - ifstream不会打开它们(perror返回“No such file or directory”) . 通过调用用户来交换数组变量以命名文件(使用cin) - ifstream打开文件 . 为什么?如何让阵列工作?
Things to Know
-
所有文件都存在于命名方案run20 ### where的文件夹中
-
所有文件都命名为S20 ### . ABC其中###与父目录相同,ABC可以从001-999开始 . 这些都是ifstream和getline可以打开的文本文件(虽然没有.txt扩展名) .
我正在编写一个程序,它将从多达150个文件中提取信息 . 我写的早期版本让用户输入文件名(使用cin) . ifstream每次都获取存储的名称并成功打开文件 . 显然,我不想输入150个文件名,因此程序将所有文件名存储为数组中的字符串以供程序使用 . 但是,当它打开文件时(在正确的路径中并使用正确的文件名和扩展名),我从perror获得的错误将返回“No such file or directory” . 如果我只是快速交换变量,以便文件名来自cin,则文件打开 . 为什么cin工作和阵列版本没有?有没有办法让阵列工作?
我也尝试过类似没有数组的东西 . 相反,在将从数组中提取文件的for循环中,文件每次都会被命名 .
这是代码(抱歉 Headers ,无法正确格式化):
#include <iostream>
#include <array>
#include <string>
#include <ctime>
#include <cstring>
#include <fstream>
#include <sstream>
using namespace std;
int main() {
//--------------------------Initial setup----------------------------------
cout << "Please give the full name of the folder you would like to open in the /Users/lucas/HPS/TDCData directory" << endl << endl;
string sFolderName;
cin >> sFolderName;
// Create path. I have mine here but you'll have to change it to something you'll
// use if you want to run the code
string sPathName = "/Users/lucas/HPS/TDCData/" + sFolderName;
//----------------Create file name array------------------------------------
// Get naming base from the folder name given
string sFileBase = "S20";
for (int i = 5; i <= sFolderName.length(); i++){
sFileBase = sFileBase + sFolderName[i];
}
//Specify range since different directories have different numbers of files
cout << "Files must be named S20###.ABC" << endl;
cout << "Specify a range for ABC" << endl;
int iFloor;
int iCeiling;
cout << "Floor: " << endl;
cin >> iFloor;
cout << "Ceiling: " << endl;
cin >> iCeiling;
// Define an array to store names and then store them
string *aFiles;
int iFilesSize = iCeiling - iFloor + 1;
aFiles = new string [iFilesSize];
cout << "Array created" << endl;
for (int i = iFloor; i <= iCeiling; i++){
string name = sFileBase;
if (i < 10){
name = name + ".00" + to_string(i);
}
else if (i < 100) {
name = name + ".0" + to_string(i);
}
else {
name = name + '.' + to_string(i);
}
aFiles[i-1] = name;
}
//----------------Open each file in aFiles----------------------
for (int i = 0; i < iFilesSize; i++){
// There are two important lines of code here. The first gets sFileName from
// aFiles. The second gets sFileName from user input using cin (this is commented out).
// Obviously, none of the last section of code is needed for the second line to work.
// The first line does not work for me. The second does.
string sFileName;
//First
sFileName = aFiles[i];
//Second
//cin >> sFileName
string sFullPath = sPathName + "/" + sFileName;
cout << "Searching ... " << sFullPath << endl << endl;
//Open file
ifstream inputFile(sFullPath);
//Check that the file opened
if (! inputFile.is_open()) {
cout << "Error reading" << sFullPath << endl;
perror("Error is: ");
return 0;
}
else {
cout << "File opened successfully..." << aFiles[i] << endl << endl;
}
}
cout << "All files opened..." << endl << endl;
return 0;
}
另外here's链接到其中一个目录的zip,用于任何有人可能想要运行的测试 . 感谢您的帮助!
2 回答
看起来你开始从索引
iFloor
填充aFiles
,而你开始从索引0
读取aFiles
.如何将
aFiles[i-1] = name;
更改为aFiles[i-iFloor] = name;
不要这样做 . 请使用像
std::vector<std::string>
这样的动态容器 .使用调试器检查实际传递给的内容
与
sFullPath
.在尝试使用数组时,无法替换获取值的流的行为 .
使输入流源透明的最佳方法是简单地使用
std::istream
引用,并且不要使用't care if it'或std::cin
std::istringstream
参考 .初始化上述
std::istringstream
所需的std::string
实例可以构建,例如使用std::ostringstream
并将str()
属性传递给std::istringstream
构造函数 .