1

I'm new to C++ and writing my master thesis and would really appreciate any help I can get!

I have a program that reads a txt file, then does a bunch of calculations, and returns a new txt file. The thing is that I want to run this program for 100+ different input files. Now I have to change the name of the input file in the code, but I would like to have it run for all the input files in my folder by itself.

I am using Visual Studio, but with little C++ experience.

Thanks :)

  • 6
    A) Make your program take in a directory as an argument and process all files in this directory. B) Write a batch file. – tadman May 02 '18 at 16:44
  • 3
    What kind of Opearating system do you use? If Linux, make a shell script – Mikhail Genkin May 02 '18 at 16:45
  • 2
    C) Make your program accept a number of filename arguments and process them in turn. – Gem Taylor May 02 '18 at 16:45
  • FirstFirst / FindNext() in the current directory or have your program read a text file that has a list of all files you want to process. That way no re-compile each time. – Michael Dorgan May 02 '18 at 16:47
  • 1
    D) Put the filenames in a file, and have the program read *that*. – Beta May 02 '18 at 16:48
  • Geez, has everyone forgotten about the existence of stdin and batch files? The only input file the program needs to know about is stdin. It doesn't need any of the complex nonsense suggested so far in answers. – Carey Gregory May 03 '18 at 01:28

4 Answers4

1

Using bash you can run them using:

$ for file in /Data/*.txt; do /path/your_program $file; done
Peter
  • 98
  • 6
1

See this snippet. Since you are using MSCV, you need to enable MFC in configuration for this console application. Also add #include "afx.h" in #include "stdafx.h" where CFileFind is defined. PopulateFromFolder() should auto load the files into the vector files.

#include "stdafx.h"
#include <iostream>
#include <string>
#include <fstream>
#include <vector>   

using namespace std;

void PopulateFromFolder(string path, vector<string>& files)
{
    CFileFind   finder;
    CString fileName;
    fileName.Format(L"%s*.*", CString(path.c_str()));
    BOOL bOk = finder.FindFile(fileName);
    while (bOk)
    {
        bOk = finder.FindNextFile();

        if (finder.IsDots())
        {
            continue;
        }
        if (!finder.IsDirectory())
        {
            CString strFileName = finder.GetFileName();
            files.push_back(CStringA(strFileName).GetString());
        }
    }
    finder.Close();
}

int main()
{
    vector<string> files;
    string path = "D:\\MyFolder\\";
    PopulateFromFolder(path, files);

    auto a = path + files[0];
    int i = 0;
    while (i< files.size()-1)
    {
        cout << "processing " << files[i + 1] << endl;
        ifstream fs(path+files[i++]);
        if (fs.is_open())
        {
            //do something
        }
        fs.close();
    }
    return 0;
}

Output:

enter image description here

seccpur
  • 4,996
  • 2
  • 13
  • 21
0

You can define format for your input files names and put then into some directory. For example,

Input1.txt
Input2.txt
...
Input111.txt

Then use some kind of for loop:

for(int i = 1; i <= 111; ++i)
{
    ifstream file("Input" + std::to_string(i) + ".txt");
    if (file.is_open())
        Operate(file);
}

If you don't know the exact number of files, you can check whether the file was openen by is_open() method. This way files with some numbers can be absent. You just loop for some max possible input file id.

This was a solution which doesn't require any dependencies. But if you don't mind it, you actually may consider Boost.Filesystem. Here is an example.

NuPagadi
  • 1,410
  • 1
  • 11
  • 31
0

You can try to use std::experimental::filesystem (http://en.cppreference.com/w/cpp/experimental/fs). I guess that directory_iterator from this library can be useful for you - it allows you to iterate over all files in a given directory. Have a look at the example provided in the documentation: http://en.cppreference.com/w/cpp/experimental/fs/directory_iterator. However, you have to make sure that you are compiling your code with a new standard (C++ 17).

Another way is to make for example a separate file containing a list of the names of all files that you want to work on. Then, you can read this list and for every file do what you need.

mks
  • 76
  • 4
  • Using `std::experimental::filesystem` actually means *not* using C++17. It's just `std::filesystem` now. – Cubbi May 07 '18 at 13:38