У меня есть файл, который я открываю с помощью функции fopen в функции init, которую я оставляю без закрытия, потому что хочу fread() это в другой функции. Для этого я объявлю глобальный статический файл, с которым могут взаимодействовать все функции?fopen и fclose, передавая файл через функции
ответ
Передача файла через единицу перевода - допустимая переменная с областью (то есть a static FILE *
). Однако он оставляет некоторые сомнения относительно того, кто отвечает за вызов fclose
. Лучшим подходом было бы иметь функцию, которая открывает возвращаемый файл FILE*
вызывающему, с предположением, что вызывающий абонент позже вызовет fclose
.
еще лучше, пусть функция, которая вызывает fread
также сделать fopen
: вместо того, чтобы открыть файл, первая функция может подготовить имя файла и сохранить его в переменной static
. Тогда функция чтения может вызвать fopen
, сделать fread
s и позвонить fclose
все в одной функции.
Это зависит от того, в какой области вам нужен FILE*
, который возвращает fopen()
. Если вы откроете файл в main()
, вы можете просто передать указатель файла другим функциям в качестве входного параметра. Что-то вроде:
int main (void)
{
FILE *pFile = fopen (...);
// validate pFile
SomeFunc (pFile);
...
fclose (pFile);
}
void SomeFunc (FILE *pF)
{
...
fread (...);
...
}
Если вы действительно не нужно по какой-то причине, я бы не объявить указатель на файл в качестве глобальной переменной - это легко забыть очистить глобалам правильно и в больших программах это трудно увидеть жизненный цикл переменной.
Лучший подход заключается в том, чтобы максимально ограничить область действия файла - это упрощает чтение/поддержание кода и освобождение ресурсов раньше.
Нет; вы должны передать указатель файла на функции в качестве параметра.
Например:
FILE *init(char *fname)
{
FILE *fp = fopen(fname, "r");
return fp;
}
void read(FILE *fp)
{
...
while (fread(buffer, sizeof buffer, 1, fp))
// do stuff
}
int main(void)
{
FILE *fp = NULL;
...
fp = init("myfile.txt");
if (fp)
read(fp);
...
}
В идеале функции должны сообщаться через параметры, возвращаемые значения и исключения (если таковые имеются); разделение состояния посредством глобальных переменных приводит к головным болям обслуживания.