Creating a Directory

Problem

You have to create a directory, and you want to do it portably, i.e., without using OS-specific APIs.

Solution

On most platforms, you will be able to use the mkdir system call that is shipped with most compilers as part of the C headers. It takes on different forms in different OSs, but regardless, you can use it to create a new directory. There is no standard C++, portable way to create a directory. Check out Example 10-15 to see how.

Example 10-15. Creating a directory

#include 
#include 

int main(int argc, char** argv) {

 if (argc < 2) {
 std::cerr << "Usage: " << argv[0] << " [new dir name]
";
 return(EXIT_FAILURE);
 }

 if (mkdir(argv[1]) == -1) { // Create the directory
 std::cerr << "Error: " << strerror(errno);
 return(EXIT_FAILURE);
 }
}

 

Discussion

The system call for creating directories differs somewhat from one OS to another, but don't let that stop you from using it anyway. Variations of mkdir are supported on most systems, so creating a directory is just a matter of knowing which header to include and what the function's signature looks like.

Example 10-15 works on Windows, but not Unix. On Windows, mkdir is declared in . It takes one parameter (the directory name), returns -1 if there is an error, and sets errno to the corresponding error number. You can get the implementation-defined error text by calling strerror or perror.

On Unix, mkdir is declared in , and its signature is slightly different. The error semantics are just like Windows, but there is a second parameter that specifies the permissions to apply to the new directory. Instead, you must specify the permissions using the traditional chmod format (see the chmod man page for specifics), e.g., 0777 means owner, group, and others all have read, write, and execute permissions. Thus, you might call it like this on Unix:

#include 
#include 
#include 

int main(int argc, char** argv) {

 if (argc < 2) {
 std::cerr << "Usage: " << argv[0] << " [new dir name]
";
 return(EXIT_FAILURE);
 }

 if (mkdir(argv[1], 0777) == -1) { // Create the directory
 std::cerr << "Error: " << strerror(errno);
 return(EXIT_FAILURE);
 }
}

If you want portability, and don't want to write all the #ifdefs yourself, you should consider using the Boost Filesystem library. You can create a directory using the create_directory function, as shown in Example 10-16, which contains a short program that creates a directory.

Example 10-16. Creating a directory with Boost

#include 
#include 
#include 
#include 
#include 

using namespace std;
using namespace boost::filesystem;

int main(int argc, char** argv) {

 // Parameter checking...

 try {
 path p = complete(path(argv[1], native));
 create_directory(p);
 }
 catch (exception& e) {
 cerr << e.what( ) << endl;
 }

 return(EXIT_SUCCESS);
}

The create_directory function creates a directory identified by the path argument you give it. If that directory already exists, a filesystem_error exception is thrown (derived from the standard exception class). For an explanation of the path class and complete function, both of which are part of the Boost Filesystem library, take a look at the discussion in Recipe Recipe 10.7. See Recipe 10.11 for an example of how to remove a directory and all the files it contains. If, on the other hand, portability is not a concern, consult your OS's proprietary filesystem API, which will most likely offer more flexibility.

See Also

Recipe 10.12

Building C++ Applications

Code Organization

Numbers

Strings and Text

Dates and Times

Managing Data with Containers

Algorithms

Classes

Exceptions and Safety

Streams and Files

Science and Mathematics

Multithreading

Internationalization

XML

Miscellaneous

Index



C++ Cookbook
Secure Programming Cookbook for C and C++: Recipes for Cryptography, Authentication, Input Validation & More
ISBN: 0596003943
EAN: 2147483647
Year: 2006
Pages: 241

Flylib.com © 2008-2020.
If you may any questions please contact us: flylib@qtcs.net