-1

I'm new to C++ programming, and I'm trying to practice file reading and writing. I'm trying to get the sizes of all the files of the current directory. Thing is, after getting the names of the files in the current directory, I place them inside of a text file. So now I'm stuck, and don't know where to go from here.

#include <iostream>
#include <fstream>
#include <algorithm>

using namespace std;

                // FILE FUNCTION

void fileStuff(){

}

                // MAIN FUNCTION

int main(int argc, char const *argv[])
{
// ERROR CHECKING
if(argc != 3){ // IF USER DOESN'T TYPE ./nameOfFile, AND THE OTHER REQUIRED ARGUMENTS.

    cout << "Incorrect. Try Again" << endl;
    exit(-1);
}

ifstream file;
string fileContents;

system("find . -type f > temp.txt");

file.open("temp.txt");

if (!file){

    cout << "Unable to open file: temp.txt" << endl;
    exit(-1);
}
while(file){

    getline(file, fileContents);
    cout << fileContents << endl;
}

file.close();
return 0;
}
Federico klez Culloca
  • 22,898
  • 15
  • 55
  • 90

1 Answers1

2

C++14 (and earlier versions, notably C++11) does not know about file systems and directories (yet). For C++17, see its file system library. Otherwise, your code is operating system specific, but Boost library has some file system support.

I am assuming you are running on Linux or some POSIX system.

Your program just uses an external command (find(1)); if you want to read from such a command, you might use popen(3) with pclose, then you won't need a temporary file. BTW, you could use find . -type f -ls.

However, you don't need to use an external command, and it is safer (and faster) to avoid that.

Pedantically, a file name could contain a newline character, and with your approach you'll need to special case that. A file name could also contain a tab character (or other control characters) and in that case find . -type f behave specifically, and you would also need to special case. In practice, it is extremely poor taste and very unlikely to have a newline or tab character in a file name and you might forget these weird cases.

You could use nftw(3). You could recursively use opendir(3) & loop on readdir(3) (and later closedir).

Once you have a file path, you would use stat(2) to get that file's metadata, including its size (field st_size). BTW the /bin/ls and /usr/bin/find programs use that.

The readdir(3) function returns a struct dirent pointer ending with d_name; you probably want to skip the two entries for . and .. (so use strcmp(3) to compare with "." and "..", or do the compare the hard way). Then you'll build a complete file path using string catenation. You might use (in genuine C++) std::string or you could use snprintf(3) or asprintf(3) for that. If you readdir the current directory . you could call stat(2) directly on d_name field.

BTW exit(-1) is incorrect (and certainly poor taste). See exit(3). A much more readable alternative is exit(EXIT_FAILURE)

Basile Starynkevitch
  • 1
  • 16
  • 251
  • 479
  • 1
    [Boost example](http://boost.2283326.n4.nabble.com/Directory-size-via-boost-filesystem-problem-td2563938.html) – MSalters Jun 01 '17 at 07:55