0

How do I read all .txt files in a certain directory? Let's say in my C:\ I have a foo.txt and a foo2.txt. Is there a way to read both of these two without having to do something like this?

string text;
string text2;

ifstream myFile ("foo.txt");
ifstream myFile2 ("foo2.txt");

while(myFile << text){
};

while(myFile2 << text2){
};

In other words, is it possible to put a wildcard *.txt to instruct to read all .txt files?

ifstream myFile ("*.txt");
Grigory Rechistov
  • 2,104
  • 16
  • 25
WWZX88
  • 39
  • 1
  • 2
  • 4
    Don't forget google is your most powerful ally as well as the [c++ docs/refs](http://www.cplusplus.com/reference/fstream/ifstream/)! Possible duplicate of [List all text files in directory in C++](https://stackoverflow.com/questions/35424519/list-all-text-files-in-directory-in-c) – Prix Mar 25 '18 at 06:09
  • did you google "how to read from file on C++" before posting here? – Sazzad Hissain Khan Mar 25 '18 at 06:09
  • 2
    This seems like a good question, @Prix neither of your links answer this question. – fireant Mar 25 '18 at 06:26
  • 1
    @SazzadHissainKhan the answer to the question you are saying the op should google is not really what's he's asking. – fireant Mar 25 '18 at 06:26
  • If the OP can _google_ it ,, then there is an answer! if that answer is in SO, thena duplicate comment would be suitable. – Mohammad Kanan Mar 25 '18 at 06:32
  • 1
    The recent C++17 standard adds a [few handy utilities for iterating directories](http://en.cppreference.com/w/cpp/filesystem). – user4581301 Mar 25 '18 at 06:35
  • Possible duplicate of [Read multiple files C++ using Boost](https://stackoverflow.com/questions/41998593/read-multiple-files-c-using-boost) – Mohammad Kanan Mar 25 '18 at 06:40
  • Don’t be a prick @prix cmon, ur link has nothing common but the word files, please delete your comment, it may confuse a moderator. Also this guy wants to read all files in a directory not print their names. – omkaartg Mar 25 '18 at 07:08
  • Use this link which @prix has given - https://stackoverflow.com/questions/35424519/list-all-text-files-in-directory-in-c . Use the code in that store all file names in a directory. Create a for loop, loop on every file name and copy all contents, that’s all folks – omkaartg Mar 25 '18 at 07:10
  • @Omkaar.K my link shows exactly what the OP needs, the first one shows the docs of `ifstream` where he can see that he cannot give it multiple files as parameters, and the second, how he can get all the files of a directory. Since he already know how to read the files its just a matter of him being able to put both together. – Prix Mar 25 '18 at 07:30

5 Answers5

3

Since I see you are using windows here is a FindFirstFile, FindNextFile. Do not have Windows machine handy so I cannot give you example but here are the resources:

FindFirstFile FindNextFile

You can than extract file name for ifstream.

Or you can use C++17 directory iterator. I have not played with this at all.

2

You'd typically do this by passing the name(s) of the files to read on the command line. Using a Linux-like shell, passing something like foo *.txt will be expanded by the shell, so foo will receive the names of the appropriate files in its argc/argv. On Windows, the shell doesn't do that, but if you're using vc++, you can link in setargv.obj to have to done automatically.

Once you've done that, you receive the file names in argc/argv, and process them from there:

int main(int argc, char **argv) { 
    if (argc < 2) {
        std::cerr << "Usage: process <filename> [filename...]\n";
        return EXIT_FAILURE;
    }

    for (int i=1; i<argc; i++) {
        std::ifstream infile(argv[i]);
        // process file
    }
}
Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
1

How do I read any .txt files in a certain directory?

The C++11 (see n3337) and C++14 standards do not know about directories. You could have a system without directories (even if it is not common today; however early MS-DOS 1 did not have directories), and you can have many different file systems.

You need support from your operating system on directories. Remember that a C++ implementation could (in theory) exist on a computer without any OS.

Even the notion of file streams (in the C++ language specification) is not required to be related to operating system files (see this); however on most C++ implementations it is practically related.

C++17 is adding a standard header <filesystem> for file systems. However, many C++ implementations don't support that yet. Please refer to the documentation of your C++ implementation and of your system.

In practice, you need support from your OS to deal with directories. You could use some framework like Boost, Qt, POCO for that. They practically are wrapping operating-system specific services or system calls related to directories.

And the notion of directory varies (in the details) with OSes and with file systems: a directory on Windows is not the same as a directory on Linux. Even the notion of working directory is slightly different.

On Linux and POSIX, see opendir(3), readdir(3), realpath(3), dirname(3), nftw(3), getcwd(3), stat(2), chdir(2), chroot(2), mkdir(2) etc... to deal with directories (see also path_resolution(7)). On Windows, it is different (see GRC's answer).

In other words, is it possible to put an asterisk next to .txt and say read all .txt files?
ifstream myFile ("*.txt");

Probably not, and it does not make any sense. Do you want to iterate on several files (then you won't deal with a single ifstream)? Do you dream of some magic mechanism -which does not exist in practice- which would concatenate all files whose name ends with .txt? In what order? What should happen if some other process is adding or removing files in that directory at the same time? What should happen with a directory which does not contain any file whose name ends with .txt ? What about a directory containing zillions of files and terabytes of data (your hardware would need hours or days to read them all!)?

On some operating systems (notably Linux), *.txt is a valid file path (of course, it smells bad and usually nobody creates such files on purpose; but it is in principle possible to create such a file). What behavior would you expect in that case? What about an hypothetical working directory contain both a *.txt file and some a.txt and b.txt? BTW, on Linux a file is really an inode(7) and the same file could have several file paths (see link(2)...) or even none of them.

Read also about globbing (which works differently on various OSes: on Unix systems, it is often done by the shell. In my incomplete understanding, on Windows, it might be done by some crt0-like startup routine).

Take several days or weeks to read Operating Systems : Three Easy Pieces to understand better the role of an OS.

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
-1

The constructor of ifstream accepts only one file.

Also please refer to Google first before asking any question to avoid multiple questions

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Thenad
  • 155
  • 2
  • 11
-2

No, you cannot pass "*.txt" to the constructor of ifstream and expect to read the content of the two files. Also you don't need two objects, using the same object you can read the content of the two files, one after the other.

fireant
  • 14,080
  • 4
  • 39
  • 48