tags:

views:

801

answers:

5

Possible Duplicate:
Delete folder with items

How to delete a non empty directory in C or C++? Is there any function? rmdir only deletes empty directory. Please provide a way without using any external library.

Also tell me how to delete a file in C or C++?

+1  A: 

You can use opendir and readdir to read directory entries and unlink to delete them.

diciu
A: 

unlink will delete a file.

remove will also delete a file but is more portable.

You might try system("rm -r ./path") if you're working on Linux, else there's also a Windows API recursive delete function.

Xorlev
`system()` is pretty much always the wrong answer.
asveikau
It has its uses, it's a quick and dirty solution.
Xorlev
@Xorlev - what is the Windows API recursive delete function?
Manuel
@Xorlev - It's just dirty! You might think it's quick - but some poor programmer will probably have to clear up your mess later on.
logout
If you correctly quote the argument and use the correct charset encoding and realize that "system" makes the whole program none multithreading safe (it changes the signals in a very bad way) you will understand why 'system' is pretty much always the wrong answer.
Lothar
+3  A: 

You want to write a function (a recursive function is easiest, but can easily run out of stack space on deep directories) that will enumerate the children of a directory. If you find a child that is a directory, you recurse on that. Otherwise, you delete the files inside. When you are done, the directory is empty and you can remove it via the syscall.

To enumerate directories on Unix, you can use opendir, readdir, and closedir. To remove you use rmdir() on an empty directory (i.e. at the end of your function, after deleting the children) and unlink() on a file. Note that on many systems the d_type member in struct dirent is not supported; on these platforms, you will have to use stat() and S_ISDIR(stat.st_mode) to determine if a given path is a directory.

On Windows, you will use FindFirstFile()/FindNextFile() to enumerate, RemoveDirectory() on empty directories, and DeleteFile() to remove files.

Here's an example that might work on Unix (completely untested):

int remove_directory(const char *path)
{
   DIR *d = opendir(path);
   size_t path_len = strlen(path);
   int r = -1;

   if (d)
   {
      struct dirent *p;

      r = 0;

      while (!r && (p=readdir(d)))
      {
          int r2 = -1;
          char *buf;
          size_t len;

          /* Skip the names "." and ".." as we don't want to recurse on them. */
          if (!strcmp(p->d_name, ".") || !strcmp(p->d_name, ".."))
          {
             continue;
          }

          len = path_len + strlen(p->d_name) + 2; 
          buf = malloc(len);

          if (buf)
          {
             struct stat statbuf;

             snprintf(buf, len, "%s/%s", path, p->d_name);

             if (!stat(buf, &statbuf))
             {
                if (S_ISDIR(statbuf.st_mode))
                {
                   r2 = remove_directory(buf);
                }
                else
                {
                   r2 = unlink(buf);
                }
             }

             free(buf);
          }

          r = r2;
      }

      closedir(d);
   }

   if (!r)
   {
      r = rmdir(path);
   }

   return r;
}
asveikau
reasonable answer but "easily run out of stackspace"?
peterchen
@peterchen Yes. I have seen it happen. It's also easier on Windows than POSIX, because `WIN32_FIND_DATA` is huge, whereas `DIR *` and `struct dirent *` are just two pointers..
asveikau
+4  A: 

The easiest way to do this is with remove_all function of the Boost.Filesystem library. Besides, the resulting code will be portable.

If you want to write something specific for Unix (rmdir) or for Windows (RemoveDirectory) then you'll have to write a function that deletes are subfiles and subfolders recursively.

EDIT

Looks like this question was already asked, in fact someone already recommended Boost's remove_all. So please don't upvote my answer.

Manuel
A: 

You can use the path functions provided by Microsoft Shell Light-weight Utility Library. Here's the one to check if the Directory is empty before you delete it. PathIsDirectoryEmpty()

Dave18