2016-12-11 2 views
0

Чтобы получить это с самого начала, это домашнее задание, я действительно хочу решить его сам, поэтому просто ответьте на вопрос и не распространяйте всю любовь StackExchange и укажите больше потенциальных проблем в моем коде, и я буду признателен это очень! :)Указатель на указатель файла, как мне это сделать?

У меня проблема с тем, что я пытаюсь сделать указатель на указатель файла. В моей основной функции я создал FILE * fp; Я передаю функцию open_file(). То, что я тогда хочу сделать, это передать указатель fp на другую написанную мной функцию, которая анализирует каждое слово. Это функция, которую я вызываю.

int 
open_file(FILE * fp) 
    { 
    /*Open the text file*/ 
    fp = fopen("mate.txt", "r"); 
    if(fp == NULL) 
     { 
     return 2; 
     } 

    return 0; 
    } 

Как я передать указатель файла в этой функции от основной(), как это

ret = open_file(&fp); 

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

Флагов я использую -g -Wall -Werror и -Wextra

+1

Dont hard-code имя файла в вашей функции. Вместо этого передайте его как аргумент –

+0

. Итак, вы не хотите улучшать свои навыки кодирования и не хотите получать прибыль от знаний опытных пользователей? Вы должны работать над своим отношением. – Olaf

+3

эта функция немного бесполезна – Stargateur

ответ

2

Только поэтому реализовать вашу идею, ввести еще один уровень косвенности:

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

... 

int 
open_file(FILE ** pfp) 
    { 
    assert(pfp != NULL); 

    /*Open the text file*/ 
    *pfp = fopen("mate.txt", "r"); 
    if (*pfp == NULL) 
     { 
     return -1; /* By convention -1 indicates failure. */ 
     } 

    return 0; 
    } 

использовать его как это:

int 
open_file(FILE ** pfp); 

... 


FILE * fp; 
int ret = open_file(&fp); 

Nicer будет:

int 
open_file(const char * file_name, FILE ** pfp) 
    { 
    int result = 0; 

    assert(file_name != NULL); 
    assert(pfp != NULL); 

    *pfp = fopen(file_name, "r"); 
    if (*pfp == NULL) 
     { 
     result = -1; /* By convention -1 indicates failure. */ 
     } 

    return result; 
    } 
+0

Красивый, спасибо! Редактировать: Вы знаете, почему я не могу просто сделать ФАЙЛ ** fp? – Salviati

+0

@Salviati: 'pfp',' fp', 'wtf' .. его просто имена .. назовите это, что вы хотите, эти имена исчезли после компиляции в любом случае! ;-) – alk

+0

@Salviati: Я использовал' pfp' как 'FILE **' является «p» на «f» ile «p» ointer. – alk

1

Определим функцию следующим образом

int 
open_file(FILE ** fp) 
    { 
    /*Open the text file*/ 
    *fp = fopen("mate.txt", "r"); 
    if(*fp == NULL) 
     { 
     return 2; 
     } 

    return 0; 
    } 

Вы не можете определить функцию как

int 
open_file(FILE * fp) 
      ^^^^^^^^ 
    { 
    /*Open the text file*/ 
    fp = fopen("mate.txt", "r"); 
    if(fp == NULL) 
     { 
     return 2; 
     } 

    return 0; 
    } 

и назовите это, как

open_file(fp); 

, потому что в этом случае функция будет иметь дело с копией исходного указателя. Параметр функции - это его локальная переменная. Любые изменения копии аргумента не влияют на сам аргумент. Исходный аргумент не изменится.

+0

Я тоже об этом думал, указатель на указатель. Но я получаю ошибку: «error: несовместимые типы при назначении типа« FILE {aka struct _IO_FILE} »из типа« FILE * {aka struct _IO_FILE *} » * fp = fopen (« mate.txt »,« r »);» (извините, неверный код ошибки) – Salviati

+1

@Salviati Если вы определили в вызывающем абоненте указатель как FILE * fp; и затем вызвал функцию, подобную ret = open_file (&fp);, тогда код должен скомпилировать. –

+0

@Salviati: Где код Влада значительно отличается от моего? – alk

2

I верьте в главную, которую вы объявили f p в качестве указателя, в вашем случае это не сработает, потому что вы передаете указатель на * fp, что означает, что при открытии указателя файла этот файл находится в стеке функции open_file, когда вы выходите из функции, вы теряете этот указатель.Вы можете сделать это в течение трех (или более) различными способами:

Первый является возвращение указатель FILE:

FILE *open_file(void) 
{ 
    return fopen("mate.txt", "r"); 
} 

FILE *fp = open_file();

Или другой вариант, чтобы передать указатель на указатель * FP:

int open_file(FILE **fp) 
{ 
    /*Open the text file*/ 
    *fp = fopen("mate.txt", "r"); 
    if(*fp == NULL) 
    { 
     return 2; 
    } 

    return 0; 
} 

FILE *fp;

open_file(&fp);

Или просто прямо в главный:

FILE *fp = fopen("mate.txt", "r");

+0

@alk Спасибо и исправлены. – koper89

Смежные вопросы