Skip to content

Instantly share code, notes, and snippets.

@t-mat
Created June 24, 2013 11:55
Show Gist options
  • Save t-mat/5849549 to your computer and use it in GitHub Desktop.
Save t-mat/5849549 to your computer and use it in GitHub Desktop.
unique_ptr for FILE*
#include <stdio.h>
#include <memory>
int main() {
std::unique_ptr<FILE, int(*)(FILE*)> fp(fopen("test.txt", "r"), fclose);
if(fp) {
char buf[4096];
while(fgets(buf, sizeof(buf), fp.get())) {
printf("%s", buf);
}
}
}
@westfly
Copy link

westfly commented Apr 2, 2019

https://stackoverflow.com/questions/26360916/using-custom-deleter-with-unique-ptr
std::unique_ptr<FILE, decltype(&fclose)> fp(fopen("test.txt", "r"), &fclose);

more convenient

@Anton-V-K
Copy link

With

namespace std
{
    template <>
    struct default_delete<FILE>
    {
        void operator () (FILE* file) const
        {
            fclose(file);
        }
    };
}

you can have shorter code:

std::unique_ptr<FILE> fp(fopen("test.txt", "r"));

@melroy89
Copy link

melroy89 commented Feb 19, 2024

What about:

struct file_deleter
{
  void operator()(std::FILE* fp)
  {
    std::pclose(fp);
  }
};

using unique_file = std::unique_ptr<std::FILE, file_deleter>;

Then use it like this:

unique_file file{popen("test.txt", "r")};

The pointer is just as big as a null-pointer. And you also get rid of the error: ignoring attributes on template argument ‘int (*)(FILE*)’ [-Werror=ignored-attributes] message.

EDIT: Change fclose to pclose.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment