My goal is simple: I'd like a to clear a directory (delete all of the sub-directories and files it contains, but not delete the directory itself) given a path, in a cross-platform way.
Most of the solutions I've found online either involve using dirent.h which, from my understanding, is non-standard and may not work on non-POSIX systems (notably Windows) or using Boost.Filesystem. However, building Boost and including it in my project is a lot to ask for if all I'd like to do is clear a directory.
Is there a way to achieve my goal in standard C++? Or, has the standard not advanced to this point yet?
A filesystems library was "added" to C++ in the "Filesystems TS", so you may be able to find an experimental implementation in your compiler's standard library implementation.
However, it's not yet part of any formal standard. My understanding is that it'll be part of C++17.
Until then, Boost it is — or your own hand-crafted code on systems that are neither Windows nor POSIX-compliant.
Related
I have searched Google but haven't found quite a direct answer to my queries.
I have been reading C++ Primer and I'm still quite new to the language, but despite how good the book is it discusses the use of the standard library but doesn't really describe where it is or where it comes from (it hasn't yet anyway). So, where is the standard library? Where are the header files that let me access it? When I downloaded CodeBlocks, did the STL come with it? Or does it automatically come with my OS?
Somewhat related, but what exactly is MinGW that came with Cobeblocks? Here it says
MinGW is a C/C++ compiler suite which allows you to create Windows executables without dependency on such DLLs
So at the most basic level is it just a collection of "things" needed to let me make C++ programs?
Apologies for the quite basic question.
"When I downloaded CodeBlocks, did the STL come with it?"
Despite it's not called the STL, but the C++ standard library, it comes with your c++ compiler implementation (and optionally packaged with the CodeBlocks IDE).
You have to differentiate IDE and compiler toolchain. CodeBlocks (the Integrated Development Environment) can be configured to use a number of different compiler toolchains (e.g. Clang or MSVC).
"Or does it automatically come with my OS?"
No, usually not. Especially not for Windows OS
"So, where is the standard library? Where are the header files that let me access it?"
They come with the compiler toolchain you're currently using for your CodeBlocks project.
Supposed this is the MinGW GCC toolchain and it's installed in the default directory, you'll find the libraries under a directory like (that's what I have)
C:\MinGW\lib\gcc\mingw32\4.8.1
and the header files at
C:\MinGW\lib\gcc\mingw32\4.8.1\include\c++
"So at the most basic level is it just a collection of "things" needed to let me make C++ programs?"
It's the Minimalist GNU toolchain for Windows. It usually comes along with the GCC (GNU C/C++ compiler toolchain), plus the MSYS minimalist GNU tools environment (including GNU make, shell, etc.).
When you have installed a C++ implementation you'll have something which implements everything necessary to use C++ source files and turn them into something running. How that is done exactly depends on the specific C++ implementation. Most often, there is a compiler which processes individual source file and translates them into object files which are then combined by a linker to produce an actual running program. That is by no means required and, e.g., cling directly interprets C++ code without compiling.
All this is just to clarify that there is no one way how C++ is implemented although the majority of contemporary C++ implementations follow the approach of compiler/linker and provide libraries as a collection of files with declarations and library files providing implementations of these declarations.
Where the C++ standard library is located and where its declarations are to be found entirely depends on the C++ implementations. Oddly, all C++ implementations I have encountered so far except cling do use a compiler and all these compilers support a -E option (although it is spelled /E for MSVC++) which preprocesses a C++ file. The typically quite large output shows locations of included files pointing at the location of the declarations. That is, something like this executed on a command line yields a file with the information about the locations:
compiler -E input.cpp > input.ii
How the compiler compiler is actually named entirely depends on the C++ implementation and is something like g++, clang++, etc. The file input.cpp is supposed to contain a suitable include directive for one of the standard C++ library headers, e.g.
#include <iostream>
Searching in the output input.ii should reveal the location of this header. Of course, it is possible that the declarations are made available by the compiler without actually including a file but just making declarations visible. There used to be a compiler like this (TenDRA) but I'm not aware of any contemporary compiler doing this (with modules being considered for standardization these may come back in the future, though).
Where the actual library file with the objects implementing the various declarations is located is an entirely different question and locating these tends to be a bit more involved.
The C++ implementation is probably installed somehow when installing CodeBlocks. I think it is just one package. On systems with a package management system like dpkg on some Linuxes it would be quite reasonable to just have the IDE have a dependency on the compiler (e.g., gcc for CodeBlocks) and have the compiler have a dependency on the standard C++ library (libstdc++ for gcc) and have the package management system sort out how things are installed.
There are several implementations of the C++ standard library. Some of the more popular ones are libstdc++, which comes packaged with GCC, libc++, which can be used with Clang, or Visual Studio's implementation by Microsoft. They use a licensed version of Dinkumware's implementation. MinGW contains a port of GCC. CodeBlocks, an IDE, allows you to choose a setup which comes packaged with a version of MinGW, or one without. Either way, you can still set up the IDE to use a different compiler if you choose. Part of the standard library implementation will also be header files, not just binaries, because a lot of it is template code (which can only be implemented in header files.)
I recommend you read the documentation for the respective technologies because they contain a lot of information, more than a tutorial or book would:
libstdc++ faq
MinGW faq
MSDN
After much research and digging into the Boost libraries documentation, I cannot find answers or high-level advice on the following questions:
Which are the requirements of Boost regarding the C++ language version? C++03? C++11? How can I now which version of Boost requires which version of the C++ language?
Does it depends on the specific library (most of the times, the .hpp file included).
Do I have to check manually (as a last resort) with all the libraries I may need and all the versions of Boost, from the latest and then moving backwards in case I need a less strict dependency?
Which are the dependencies with the C++ Standard Library?
Context:
I am evaluating the use of Boost on an embedded platform (MCU with limited and no virtual memory, no underlying OS).
I have GCC 4.8.1 with C++11 support.
We do not have a complete C++ Standard Library for this platform.
I was hoping to use Boost as a complement and substitute of the C++ Standard Library, hence my research on the topics asked above.
I appreciate the high quality of the Boost project documentation, however, I could not find any reference to the above topics in the official documentation. Maybe I have missed something.
P.S.: A gente introduction to the historically complex topic of C++ language versions, Standard Library and Boost libraries,
http://news.dice.com/2013/03/15/comparing-the-c-standard-and-boost-2/
http://beta.boost.org/development/tests/master/developer/summary.html
This lists some of the platforms boost is tested against.
Every release, boost mentions which platforms it has been tested against.
It is expected to work on more platforms than those listed, but there are no guarantees.
The support and evolution of a boost library in terms of supporting new c++ features is not tightly related to the other libraries. Since boost has been living mainly in a mono standard world (c++03), it was implied that it works in c++03. But as boost people tend to do stuff in a smart way, for the libraries who now support c++11 features, they either use some feature emulation system to keep it working on c++03 or they test for your configuration and if you can't use some advanced stuff then they just disable it.
So basically there is no language standard requirements, it works on all c++03/C++11/C++14 with different features sets.
For other requirements (namely parts of the STL) it directly depends on the libraries you want. The best way is to test. You might find a way to launch their unit test on your plateforme to see how much is working.
You might also want to check Boost Config which is the library that all others use to check for features.
I want to know, or get a clue how to search through a directory in C++ with its own standard libraries or to see if it is possible at all.
Currently I have found several solution to searching directory, but they all use some external libraries such as this SO question:
recursive folder scanning in c++
How should we approach this?
There is no filesystem facilities in the C++ standard. There is a technical specification for it which may be included in a future version of C++.
Until then, you will have to use platform specific functions or a library that wraps them. Apparently the new proposal is almost the same as boost's API, so I recommend using boost even if it's ubiquitousness wasn't good enough reason already.
This is been a curiosity of mine for a while: how do you traverse a directory tree without using boost or any third-party library? Just plain ol' C++ (examples in 98, 99, 01, 0x and 1x specs are okay.)? It was done back in the day before boost existed so there's got to be a way to do it.
Please take a look at http://en.wikipedia.org/wiki/Dirent.h
The reference also has a link to dirent.h implementation for Windows or you can use cygwin
If you want to just do it for Windows you can build upon this example
http://msdn.microsoft.com/en-us/library/aa365200%28VS.85%29.aspx
There are no standard filesystem functions, so you won't get any answers that use "plain C++". For POSIX systems, opendir is used. For Windows, FindFirstFile. I'm not sure about other OSes.
There's a reason people recommend Boost Filesystem—it's portable and takes care of all these details for you.
As of the adoption of the C++17 standard there exists a <filesystem> header included in the language that does exactly this. See your compiler's documentation to determine if it's supported.
I can't seem to find the _findfirst / findfirst, _findnext / findnext API on gcc for Linux, and would actually rather use the Standard Template Library (STL) for that if it is included there.
Does anyone know what API there is available for listing files in a directory under Linux for C++ (gcc)?
It's not a C++-style API, but the API you aren't finding (the Linux/Unix correspondent of DOS/Windows-style findfirst/findnext) is opendir/readdir/closedir.
The main advantage of using opendir/readdir/closedir is that you do not need any extra library (it's part of the C library, which you are already using). In fact, the Boost filesystem library uses opendir/readdir/closedir to get the list of files in a directory.
References:
http://www.opengroup.org/onlinepubs/009695399/functions/opendir.html
http://www.opengroup.org/onlinepubs/009695399/functions/readdir.html
http://www.opengroup.org/onlinepubs/009695399/functions/closedir.html
Check out the Boost.Filesystem library.
In particular, the basic_directory_iterator.
The STL does not, yet, have functions for listing files in a directory. But it does have functions for opening files you are already aware of.
Aside from Boost.Filesystem, there is also STLSoft
Since C++17 the standard library contains std::filesystem which has its source in Boost.Filesystem. Nowadays std::filesystem::directory_iterator is the obvious choice since it is platform-independent, offers better abstraction than _findfirst/findnext/opendir/readdir/closedir and doesn't introduce any dependencies. If you can't use a C++17-compliant compiler use Boost for now and switch over later.