ifstream打开由cin命名的文件,但不是从数组中提取的文件。 cin和常规字符串定义之间有什么区别吗?

时间:2015-05-27 22:54:33

标签: c++ arrays file ifstream cin

TL; DR文件名存储为数组中的字符串(使用new) - ifstream不会打开它们(perror返回"没有这样的文件或目录")。通过调用用户来交换数组变量来命名文件(使用cin) - ifstream打开文件。为什么?如何使阵列工作?

需要了解的事项

  • 所有文件都存在于命名方案run20 ### where
  • 的文件夹中
  • 所有文件都命名为S20 ###。ABC,其中###与父目录相同,ABC可以从001-999开始。这些都是ifstream和getline可以打开的文本文件(虽然没有.txt扩展名)。

我正在编写一个程序,用于从多达150个文件中提取信息。我写的早期版本让用户输入文件名(使用cin)。 ifstream每次都获取存储的名称并成功打开文件。显然,我不想输入150个文件名,因此程序将所有文件名存储为数组中的字符串以供程序使用。但是,当它打开文件时(在正确的路径中并使用正确的文件名和扩展名),我从perror获得的错误返回"没有这样的文件或目录。"如果我只是快速交换变量,以便文件名来自cin,则文件打开。为什么cin工作和阵列版本没有?有没有办法让阵列工作?

我也尝试过类似没有阵列的东西。相反,在从数组中提取文件的for循环中,每次都会命名文件。

以下是代码(抱歉标题,无法正确格式化):

#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 个答案:

答案 0 :(得分:0)

当您从索引aFiles开始阅读iFloor时,您似乎从索引aFiles开始填充0

如何将aFiles[i-1] = name;更改为aFiles[i-iFloor] = name;

答案 1 :(得分:0)

  

“TL; DR文件名存储为数组中的字符串(使用新的)”

不要这样做。请改用std::vector<std::string>之类的动态容器。

  

“ - ifstream不会打开它们(perror返回”没有这样的文件或目录“)。”

使用调试器检查实际传递给

的内容
ifstream inputFile(sFullPath);

sFullPath

  

“通过调用用户来交换数组变量来命名文件(使用cin) - ifstream打开文件。为什么?如何让数组工作?”

在尝试使用数组时,您无法替换获取值的流的行为。

使输入流源透明的最佳方法是简单地使用std::istream引用,而不关心它是std::cin还是例如std::istringstreamstd::string参考。

初始化提到的std::istringstream所需的std::ostringstream实例可以构建,例如使用str()并将std::istringstream属性传递给div.gcontainer{ position: fixed; margin: 0; padding: 0; left: 0; top: 0; width: 100%; height: 100%; } div.gcontainer img{ position:relative; max-width:100%; max-height:100%; } 构造函数。