How to delete a folder in C++?

C++Delete Directory

C++ Problem Overview


How can I delete a folder using C++?

If no cross-platform way exists, then how to do it for the most-popular OSes - Windows, Linux, Mac, iOS, Android? Would a POSIX solution work for all of them?

C++ Solutions


Solution 1 - C++

I strongly advise to use Boost.FileSystem.

http://www.boost.org/doc/libs/1_38_0/libs/filesystem/doc/index.htm

In your case that would be

boost::filesystem::remove_all(yourPath)

Solution 2 - C++

With C++17 you can use std::filesystem, in C++14 std::experimental::filesystem is already available. Both allow the usage of filesystem::remove().

C++17:

#include <filesystem>
std::filesystem::remove("myEmptyDirectoryOrFile"); // Deletes empty directories or single files.
std::filesystem::remove_all("myDirectory"); // Deletes one or more files recursively.

C++14:

#include <experimental/filesystem>
std::experimental::filesystem::remove("myDirectory");

Note 1: Those functions throw filesystem_error in case of errors. If you want to avoid catching exceptions, use the overloaded variants with std::error_code as second parameter. E.g.

std::error_code errorCode;
if (!std::filesystem::remove("myEmptyDirectoryOrFile", errorCode)) {
    std::cout << errorCode.message() << std::endl;
}

Note 2: The conversion to std::filesystem::path happens implicit from different encodings, so you can pass strings to filesystem::remove().

Solution 3 - C++

Delete folder (sub_folders and files) in Windows (VisualC++) not using Shell APIs, this is the best working sample:

#include <string>
#include <iostream>

#include <windows.h>
#include <conio.h>


int DeleteDirectory(const std::string &refcstrRootDirectory,
                    bool              bDeleteSubdirectories = true)
{
  bool            bSubdirectory = false;       // Flag, indicating whether
                                               // subdirectories have been found
  HANDLE          hFile;                       // Handle to directory
  std::string     strFilePath;                 // Filepath
  std::string     strPattern;                  // Pattern
  WIN32_FIND_DATA FileInformation;             // File information


  strPattern = refcstrRootDirectory + "\\*.*";
  hFile = ::FindFirstFile(strPattern.c_str(), &FileInformation);
  if(hFile != INVALID_HANDLE_VALUE)
  {
    do
    {
      if(FileInformation.cFileName[0] != '.')
      {
        strFilePath.erase();
        strFilePath = refcstrRootDirectory + "\\" + FileInformation.cFileName;

        if(FileInformation.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
        {
          if(bDeleteSubdirectories)
          {
            // Delete subdirectory
            int iRC = DeleteDirectory(strFilePath, bDeleteSubdirectories);
            if(iRC)
              return iRC;
          }
          else
            bSubdirectory = true;
        }
        else
        {
          // Set file attributes
          if(::SetFileAttributes(strFilePath.c_str(),
                                 FILE_ATTRIBUTE_NORMAL) == FALSE)
            return ::GetLastError();

          // Delete file
          if(::DeleteFile(strFilePath.c_str()) == FALSE)
            return ::GetLastError();
        }
      }
    } while(::FindNextFile(hFile, &FileInformation) == TRUE);

    // Close handle
    ::FindClose(hFile);

    DWORD dwError = ::GetLastError();
    if(dwError != ERROR_NO_MORE_FILES)
      return dwError;
    else
    {
      if(!bSubdirectory)
      {
        // Set directory attributes
        if(::SetFileAttributes(refcstrRootDirectory.c_str(),
                               FILE_ATTRIBUTE_NORMAL) == FALSE)
          return ::GetLastError();

        // Delete directory
        if(::RemoveDirectory(refcstrRootDirectory.c_str()) == FALSE)
          return ::GetLastError();
      }
    }
  }

  return 0;
}


int main()
{
  int         iRC                  = 0;
  std::string strDirectoryToDelete = "c:\\mydir";


  // Delete 'c:\mydir' without deleting the subdirectories
  iRC = DeleteDirectory(strDirectoryToDelete, false);
  if(iRC)
  {
    std::cout << "Error " << iRC << std::endl;
    return -1;
  }

  // Delete 'c:\mydir' and its subdirectories
  iRC = DeleteDirectory(strDirectoryToDelete);
  if(iRC)
  {
    std::cout << "Error " << iRC << std::endl;
    return -1;
  }

  // Wait for keystroke
  _getch();

  return 0;
}

Source: http://www.codeguru.com/forum/showthread.php?t=239271

Solution 4 - C++

The directory should be empty.

BOOL RemoveDirectory( LPCTSTR lpPathName );

Solution 5 - C++

void remove_dir(char *path)
{
        struct dirent *entry = NULL;
        DIR *dir = NULL;
        dir = opendir(path);
        while(entry = readdir(dir))
        {   
                DIR *sub_dir = NULL;
                FILE *file = NULL;
                char abs_path[100] = {0};
                if(*(entry->d_name) != '.')
                {   
                        sprintf(abs_path, "%s/%s", path, entry->d_name);
                        if(sub_dir = opendir(abs_path))
                        {   
                                closedir(sub_dir);
                                remove_dir(abs_path);
                        }   
                        else 
                        {   
                                if(file = fopen(abs_path, "r"))
                                {   
                                        fclose(file);
                                        remove(abs_path);
                                }   
                        }   
                }   
        }   
        remove(path);
}

Solution 6 - C++

Use SHFileOperation to remove the folder recursivelly

Solution 7 - C++

The directory must be empty and your program must have permissions to delete it

but the function called rmdir will do it

rmdir("C:/Documents and Settings/user/Desktop/itsme") 

Solution 8 - C++

You can also try this if you are on linux:

system("rm -r path");

Solution 9 - C++

This works for deleting all the directories and files within a directory.

#include <iostream>
#include <cstring>
#include <cstdlib>
using namespace std;
int main()
{
	cout << "Enter the DirectoryName to Delete : ";
	string directoryName;
	cin >> directoryName;
	string a = "rmdir /s /q " + directoryName;
	system(a.c_str());
	return 0;
}

Solution 10 - C++

The C++ Standard defines the remove() function, which may or may not delete a folder, depending on implementation. If it doesn't you need to use an implementation specific function such as rmdir().

Solution 11 - C++

I do not have the "reputation" to comment, so I have to make an answer.

As far as I could see the previous solution for Windows contains an error (in checking the ".": it does not delete directories like .ssh for example).

Furthermore, the (now necessary) management of UTF-8 paths is missing.

// OK we want the UTF-8 compatible functions
#ifndef UNICODE
#define UNICODE
#endif

#include <stdio.h>
#include <windows.h>
#include <string>
#include <assert.h>


// 16bit wide string to UTF-8 
std::string wtou(const wchar_t* i_string) 
{
	assert(sizeof(wchar_t)==2);		// Not always true 
	assert((wchar_t)(-1)==65535);	// not too big
	std::string myresult;
	if (!i_string) 
		return myresult;
	for (; *i_string; i_string++) 
	{
		if (*i_string<128) 
			myresult+=*i_string;
		else 
		if (*i_string<2048) 
			myresult+=192+*i_string/64, myresult+=128+*i_string%64;
		else 
			myresult+=224+*i_string/4096, myresult+=128+*i_string/64%64, myresult+=128+*i_string%64;
	}
	return myresult;
}

// UTF-8 to wide string
std::wstring utow(const char* i_string) 
{
	assert(sizeof(wchar_t)==2);
	assert((wchar_t)(-1)==65535);
	std::wstring myresult;
	if (!i_string) 
		return myresult;
	const unsigned char* s=(const unsigned char*)i_string;
	for (; s && *s; s++) 
	{
		if (s[0]<128) 
			myresult+=s[0];
		else 
		if (s[0]>=192 && s[0]<224 && s[1]>=128 && s[1]<192)
			myresult+=(s[0]-192)*64+s[1]-128, ++i_string;
		else 
		if (s[0]>=224 && s[0]<240 && s[1]>=128 && s[1]<192 && s[2]>=128 && s[2]<192)
			myresult+=(s[0]-224)*4096+(s[1]-128)*64+s[2]-128, s+=2;
	}
	return myresult;
}

int win_erredbarras(const std::string &i_path,bool i_flagrecursive=true)
{
	bool	flagdebug=true;
	bool	flagsubdir=false;
	HANDLE	myhandle;
	std::wstring wfilepath;
	WIN32_FIND_DATA findfiledata;

	std::string pattern=i_path+"\\*.*";
  
	std::wstring wpattern	=utow(pattern.c_str());
	std::wstring wi_path	=utow(i_path.c_str());

	myhandle=FindFirstFile(wpattern.c_str(),&findfiledata);
  
	if (myhandle!=INVALID_HANDLE_VALUE)
	{
		do
		{
			std::string t=wtou(findfiledata.cFileName);
			
			if ((t!=".") && (t!=".."))
			{
				wfilepath=wi_path+L"\\"+findfiledata.cFileName;
				if (findfiledata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
				{
					if (i_flagrecursive)
					{
						const std::string temp(wfilepath.begin(),wfilepath.end());
						if (flagdebug)
							printf("\n\nDelete directory   %s\n",temp.c_str());
						int myresult=win_erredbarras(temp,i_flagrecursive);
						if (myresult)
							return myresult;
					}
					else
						flagsubdir=true;
				}
				else
				{
					const std::string ttemp(wfilepath.begin(), wfilepath.end() );
					if (flagdebug)
						printf("Try to delete file %s\n",ttemp.c_str());

					if (SetFileAttributes(wfilepath.c_str(),FILE_ATTRIBUTE_NORMAL) == FALSE)
					{
						if (flagdebug)
							printf("31019: ERROR cannot change attr of file %s\n",ttemp.c_str());
						return GetLastError();
					}
					
					if (DeleteFile(wfilepath.c_str())==FALSE)
					{
						if (flagdebug)
							printf("31025: ERROR highlander file %s\n",ttemp.c_str());
						return GetLastError();
					}
				}
			}
		} while(FindNextFile(myhandle,&findfiledata)==TRUE);

		FindClose(myhandle);

		DWORD myerror=GetLastError();
		if (myerror==ERROR_NO_MORE_FILES)
		{
			if (!flagsubdir)
			{
				const std::string dtemp(wi_path.begin(), wi_path.end());
				
				if (flagdebug)
					printf("Delete no subdir   %s\n",dtemp.c_str());
							
				if (SetFileAttributes(wi_path.c_str(),FILE_ATTRIBUTE_NORMAL)==FALSE)
				{
					if (flagdebug)
						printf("30135: ERROR cannot change folder attr %s\n",dtemp.c_str());
					return GetLastError();
				}
								
				if (RemoveDirectory(wi_path.c_str())==FALSE)
				{
					if (flagdebug)
						printf("31047: ERROR highlander dir %s\n",dtemp.c_str());
					return GetLastError();
				}
			}
		}
		else
			return myerror;
	}
	return 0;
}

int main()
{
	win_erredbarras("z:\\knb",true);
	return 0;
}

Now I put a UNIX/Linux version, based on fixed previous functions

#include <stdio.h>
#include <string>
#include <dirent.h>
#include <sys/stat.h>

/// secondary functions to be #ifdeffed on Windows
bool isdirectory(std::string i_filename)
{
	if (i_filename.length()==0)
		return false;
	else
		return i_filename[i_filename.size()-1]=='/';
}
bool delete_file(const char* i_filename) 
{
	return remove(i_filename)==0;
}
bool delete_dir(const char* i_directory) 
{
	return remove(i_directory)==0;
}

int erredbarras(const std::string &i_path,bool i_flagrecursive=true)
{
	bool	flagdebug=true;
	bool 	risultato=false;

	DIR *d=opendir(i_path.c_str());

	if (d) 
	{
		struct dirent *p;
		risultato=true;
		while (risultato && (p=readdir(d))) 
		{
			if (!strcmp(p->d_name, ".") || !strcmp(p->d_name, ".."))
				continue;
			bool risultato2=false;
			struct stat statbuf;
			
			std::string temp;
			if (isdirectory(i_path))
				temp=i_path+p->d_name;
			else
				temp=i_path+"/"+p->d_name;

			if (!stat(temp.c_str(), &statbuf)) 
			{
				if (S_ISDIR(statbuf.st_mode))
					risultato2=erredbarras(temp);
				else
				{
					if (flagdebug)
						printf("Delete file %s\n",temp.c_str());
					risultato2=delete_file(temp.c_str());
				}
			}
			risultato=risultato2;
		}
		closedir(d);
	}

	if (risultato)
	{
		if (flagdebug)
			printf("Delete dir  %s\n\n",i_path.c_str());
		delete_dir(i_path.c_str());
	}
   return risultato;
}


int main()
{
	printf("Risultato %d\n",erredbarras("/tmp/knb/"));
	return 0;
}

Solution 12 - C++

//For windows:

#include <direct.h>


if(_rmdir("FILEPATHHERE") != -1)
{
  //success     
} else {
  //failure
}

Solution 13 - C++

Try use system "rmdir -s -q file_to_delte".
This will delete the folder and all files in it.

Solution 14 - C++

My own implementation based off hB0 that also allows you to view the number of files in each folder also with a little performance boost.

#include <string>
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <windows.h>
#include <conio.h>

union seperated {
  struct {
	unsigned int low;
	unsigned int high;
  } uint;
  unsigned long long ull;
};

unsigned long long num_dirs  = 1;
unsigned long long num_files = 0;
seperated size_files;

int DeleteDirectory( char* refRootDirectory );		//predeclare it

int DeleteDirectory( char* refRootDirectory ) {
	HANDLE		hFile;				// Handle to directory
	std::string	strFilePath;			// Filepath
	WIN32_FIND_DATA	FileInformation;	// File information
	int		dwError;			// Folder deleting error
	std::string	strPattern;			// Pattern
	
	strPattern = (std::string)(refRootDirectory) + "\\*.*";
	hFile = ::FindFirstFile( strPattern.c_str(), &FileInformation );
	
	if( hFile != INVALID_HANDLE_VALUE )
	{
		do {
			if( FileInformation.cFileName[0] != '.' ) {
				strFilePath.erase();
				strFilePath = std::string(refRootDirectory) + "\\" + FileInformation.cFileName;
				
				if( FileInformation.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) {
					DeleteDirectory( (char*)strFilePath.c_str() );
					
					dwError = ::GetLastError();
					if( dwError != ERROR_NO_MORE_FILES ) {
						std::cout << "!ERROR!: [[" << strFilePath.c_str() << "]]\n";
						return dwError;
					} else {
						// Set directory attributes
						if( ! ::SetFileAttributes(refRootDirectory,FILE_ATTRIBUTE_NORMAL) ) {
							std::cout << "!ERROR!: [[" << strFilePath.c_str() << "]]\n";
							return ::GetLastError();
						}
						
						// Delete directory
						if( ! ::RemoveDirectory(refRootDirectory) ) {
							std::cout << "!ERROR!: [[" << strFilePath.c_str() << "]]\n";
							return ::GetLastError();
						}
					}
					
					++num_dirs;
				} else {
					
					// Set file attributes
					if( ! ::SetFileAttributes(strFilePath.c_str(),FILE_ATTRIBUTE_NORMAL) ) {
						std::cout << "!ERROR!: [[" << strFilePath.c_str() << "]]\n";
						return ::GetLastError();
					}
					
					// Delete file
					if ( ! ::DeleteFile(strFilePath.c_str()) ) {
						std::cout << "!ERROR!: [[" << strFilePath.c_str() << "]]\n";
						return ::GetLastError();
					}
					
					size_files.ull	     += FileInformation.nFileSizeLow;
					size_files.uint.high += FileInformation.nFileSizeHigh;
					
					++num_files;
				}
			}
		} while( ::FindNextFile(hFile,&FileInformation) );

		// Close handle
		::FindClose( hFile  );
	}

	return 0;
}

unsigned long long num_files_total=0;
unsigned long long num_dirs_total=0;
unsigned long long total_size_files=0;

void my_del_directory( char* dir_name ) {
	int iRC = DeleteDirectory( dir_name );
	//int iRC=0;
	
	std::cout << "\"" << dir_name << "\""
			 "\n    Folders: " << num_dirs
		  << "\n    Files:   " << num_files
		  << "\n    Size:    " << size_files.ull << " Bytes";
	if(iRC)
	{
		std::cout << "\n!ERROR!: " << iRC;
	}
	std::cout << "\n\n";
	
	num_dirs_total   += num_dirs;
	num_files_total  += num_files;
	total_size_files += size_files.ull;
	num_dirs  = 1;
	num_files = 0;
	size_files.ull = 0ULL;
	return;
}

int main( void )
{
	size_files.ull = 0ULL;
	
	my_del_directory( (char*)"C:\Windows\temp"		);
		// This will clear out the System temporary directory on windows systems
	
	std::cout << "\n\nResults" << "\nTotal Folders: " << num_dirs_total
				   << "\nTotal Files:   " << num_files_total
				   << "\nTotal Size:    " << total_size_files << " Bytes\n";
	
	return 0;
}

Solution 15 - C++

For linux (I have fixed bugs in code above):

void remove_dir(char *path)
{
        struct dirent *entry = NULL;
        DIR *dir = NULL;
        dir = opendir(path);
        while(entry = readdir(dir))
        {   
                DIR *sub_dir = NULL;
                FILE *file = NULL;
                char* abs_path new char[256];
                 if ((*(entry->d_name) != '.') || ((strlen(entry->d_name) > 1) && (entry->d_name[1] != '.')))
                {   
                        sprintf(abs_path, "%s/%s", path, entry->d_name);
                        if(sub_dir = opendir(abs_path))
                        {   
                                closedir(sub_dir);
                                remove_dir(abs_path);
                        }   
                        else 
                        {   
                                if(file = fopen(abs_path, "r"))
                                {   
                                        fclose(file);
                                        remove(abs_path);
                                }   
                        }   
                }
                delete[] abs_path;   
        }   
        remove(path);
}

For windows:

void remove_dir(const wchar_t* folder)
{
    std::wstring search_path = std::wstring(folder) + _T("/*.*");
    std::wstring s_p = std::wstring(folder) + _T("/");
    WIN32_FIND_DATA fd;
    HANDLE hFind = ::FindFirstFile(search_path.c_str(), &fd);
    if (hFind != INVALID_HANDLE_VALUE) {
        do {
            if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
                if (wcscmp(fd.cFileName, _T(".")) != 0 && wcscmp(fd.cFileName, _T("..")) != 0)
                {
                    remove_dir((wchar_t*)(s_p + fd.cFileName).c_str());
                }
            }
            else {
                DeleteFile((s_p + fd.cFileName).c_str());
            }
        } while (::FindNextFile(hFind, &fd));
        ::FindClose(hFind);
        _wrmdir(folder);
    }
}

Solution 16 - C++

If you are using the Poco library, here is a portable way to delete a directory.

#include "Poco/File.h"
...
...
Poco::File fooDir("/path/to/your/dir");
fooDir.remove(true);

The remove function when called with "true" means recursively delete all files and sub directories in a directory.

Solution 17 - C++

If you are using windows, then take a look at this link. Otherwise, you may look for your OS specific version api. I don't think C++ comes with a cross-platform way to do it. At the end, it's NOT C++'s work, it's the OS's work.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser88240View Question on Stackoverflow
Solution 1 - C++Edouard A.View Answer on Stackoverflow
Solution 2 - C++Roi DantonView Answer on Stackoverflow
Solution 3 - C++hB0View Answer on Stackoverflow
Solution 4 - C++VinayView Answer on Stackoverflow
Solution 5 - C++user4385463View Answer on Stackoverflow
Solution 6 - C++user1803888View Answer on Stackoverflow
Solution 7 - C++TStamperView Answer on Stackoverflow
Solution 8 - C++B FaleyView Answer on Stackoverflow
Solution 9 - C++Akash Kumar SinghalView Answer on Stackoverflow
Solution 10 - C++anonView Answer on Stackoverflow
Solution 11 - C++Franco CorbelliView Answer on Stackoverflow
Solution 12 - C++JP_View Answer on Stackoverflow
Solution 13 - C++xluView Answer on Stackoverflow
Solution 14 - C++Jack GView Answer on Stackoverflow
Solution 15 - C++Svyatoslav KovalevView Answer on Stackoverflow
Solution 16 - C++James SelvakumarView Answer on Stackoverflow
Solution 17 - C++J.W.View Answer on Stackoverflow