What is the correct way to declare and use a FILE

2020-08-26 11:28发布

问题:

What is the correct way to declare and use a FILE * pointer in C/C++? Should it be declared global or local? Can somebody show a good example?

回答1:

It doesn't matter at all whether it's local or global. The scope of the file pointer has nothing to do with its use.

In general, it's a good idea to avoid global variables as much as possible.

Here's a sample showing how to copy from input.txt to output.txt:

#include <stdio.h>
int main(void) {
    FILE *fin, *fout; int c;

    // Open both files, fail fast if either no good.

    if ((fin = fopen("input.txt", "r")) == NULL) {
        fprintf(stderr, "Cannot read from input.txt");
        return 1;
    }

    if ((fout = fopen("output.txt", "w")) == NULL) {
        fprintf(stderr, "Cannot write to output.txt");
        fclose(fin);
        return 1;
    }

    // Transfer character by character.

    while ((c = fgetc(fin)) >= 0) {
        fputc (c, fout);
    }

    // Close both files and exit.

    fclose(fin);
    fclose(fout);

    return 0;
}


回答2:

It's just an ordinary pointer like any other.

FILE *CreateLogFile() 
{
    return fopen("logfile.txt","w"); // allocates a FILE object and returns a pointer to it
}

void UsefulFunction()
{
   FILE *pLog = CreateLogFile(); // it's safe to return a pointer from a func
   int resultsOfWork = DoSomeWork();
   fprintf( pLog, "Work did %d\n", resultsOfWork );  // you can pass it to other functions
   fclose( pLog ); // just be sure to clean it up when you are done with fclose()
   pLog = NULL;    // and it's a good idea to overwrite the pointer afterwards
                   // so it's obvious you deleted what it points to
}


回答3:

Here is the first hit on google for "file io in c"

http://www.cs.bu.edu/teaching/c/file-io/intro/

Here is the third hit from gamedev with more of a C++ slant

http://www.gamedev.net/reference/articles/article1127.asp

You declare the pointer in the scope that you need it.



回答4:

int main(void)
{
  char c;
  FILE *read;
  read = fopen("myfile", "r"); // opens "myfile" for reading
  if(read == NULL)
  {
    perror("Error: could not open \"myfile\" for reading.\n");
    exit(1);
  }
  c = fgetc(read);
  fclose(read);
  printf("The first character of myfile is %c.\n", c);
  return 0;
}

You're perfectly allowed to declare global filehandles if you like, just like any other variable, but it may not be recommended.

This is the C way. C++ can use this, but I think there's a more C++ friendly way of doing it. As a note, I hate it when questions are marked C/C++, because C and C++ are not the same language and do not work the same. C++ has a lot of different ways to do things that C doesn't have, and they may be easier for you to do in the context of C++ but are not valid C. So while this will work for either language, it's not what you want if you predominantly use C++.

EDIT: Added some error checking. Always use error checking in your code.



回答5:

First, keep in mind that a file pointer (and the associated allocated structure) is based on the lower level open() read() write() calls. The associated file descriptor (obtained by fileno(file_pointer) is the least interesting thing, but something you might want to watch your scope with.

If your going to declare a file pointer as global in a module, its usually a very good idea to keep it static (contained within that module / object file). Sometimes this is a little easier than storing it in a structure that is passed from function to function if you need to write something in a hurry.

For instance, (bad)

#include <stdio.h>
#include ...

#define MY_LOG_FILE "file.txt"

FILE *logfile

Better done as:

#include <stdio.h>

#define MY_LOG_FILE "file.txt"

static FILE *logfile;

int main(void)
{

UNLESS, you need several modules to have access to that pointer, in which case you're better off putting it in a structure that can be passed around.

If its needed only in one module, consider declaring it in main() and letting other functions accept a file pointer as an argument. So, unless your functions within the module have so many arguments that another would be unbearable .. there's (usually) no reason to declare a file pointer globally.

Some logging libraries do it, which I don't care for ... especially when dealing with re-entrant functions. Nevermind C's monolithic namespace :)



标签: c++ c file