Как правильно объявить и использовать указатель FILE * в C / C ++? - PullRequest
8 голосов
/ 26 февраля 2009

Как правильно объявить и использовать указатель FILE * в C / C ++? Должно ли оно быть объявлено глобальным или локальным? Может кто-нибудь показать хороший пример?

Ответы [ 5 ]

18 голосов
/ 26 февраля 2009

Не имеет значения, локальный он или глобальный. Область указателя файла не имеет ничего общего с его использованием.

В целом, лучше избегать глобальных переменных, насколько это возможно.

Вот пример, показывающий, как копировать из input.txt в 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;
}
4 голосов
/ 26 февраля 2009

Это просто обычный указатель, как и любой другой.

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
}
1 голос
/ 26 февраля 2009
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;
}

Вам разрешено объявлять глобальные файловые дескрипторы, если хотите, как и любую другую переменную, но это не рекомендуется.

Это путь C. C ++ может использовать это, но я думаю, что есть более дружественный C ++ способ сделать это. Как примечание, я ненавижу, когда вопросы помечены C / C ++, потому что C и C ++ не один и тот же язык и не работают одинаково. В C ++ есть много разных способов делать вещи, которых нет в C, и они могут быть проще для вас в контексте C ++, но не являются допустимыми C. Поэтому, хотя это будет работать для любого языка, это не то, что вы хотите, если вы используете преимущественно C ++.

EDIT: добавлена ​​проверка ошибок. Всегда используйте проверку ошибок в вашем коде.

1 голос
/ 26 февраля 2009

Вот первый хит на Google для "файла IO в C"

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

Вот третий хит от gamedev с большим уклоном C ++

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

Вы объявляете указатель в нужной вам области.

0 голосов
/ 26 февраля 2009

Во-первых, имейте в виду, что указатель файла (и связанная с ним распределенная структура) основан на вызовах open () read () write () нижнего уровня. Связанный файловый дескриптор (полученный с помощью fileno (file_pointer) - наименее интересная вещь, но кое-что, с чем вы, возможно, захотите просмотреть свою область.

Если вы собираетесь объявить указатель файла глобальным в модуле, обычно очень хорошая идея сохранить его статичным (содержится в этом модуле / объектном файле). Иногда это немного проще, чем хранить его в структуре, которая передается от функции к функции, если вам нужно что-то написать в спешке.

Например, (плохо)

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

#define MY_LOG_FILE "file.txt"

FILE *logfile

Лучше сделать как:

#include <stdio.h>

#define MY_LOG_FILE "file.txt"

static FILE *logfile;

int main(void)
{

ЕСЛИ вам нужно несколько модулей, чтобы иметь доступ к этому указателю, и в этом случае вам лучше поместить его в структуру, которую можно передавать.

Если это необходимо только в одном модуле, рассмотрите его объявление в main () и разрешение другим функциям принимать указатель файла в качестве аргумента. Таким образом, если ваши функции внутри модуля не имеют столько аргументов, что другой будет невыносимым ... обычно (обычно) нет причин объявлять файловый указатель глобально.

Некоторые библиотеки журналов делают это, что мне безразлично ... особенно при работе с реентерабельными функциями. Монолитное пространство имен Nevermind C:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...