2015-01-16 3 views
2

У меня была проблема с указателями. Я хочу прочитать двоичный файл с функцией, а затем использовать прочитанные данные в основном. Проблема в том, что мне пришлось передать указатель на массив структуры, чтобы использовать данные в основном.Указатель на массив функции struct в функции

Код:

#define TMOLDEO 8 
#define TAM 41 


struct fichpiezas{ 
    int codPieza; 
    float dimPieza; 
    float costePieza[TMOLDEO]; 
}; 

int leer_fichero(struct fichpiezas *vpiezas[]); 

int main(int argc, const char * argv[]) { 

    struct fichpiezas vpiezas[TAM]; 

    leer_fichero(&vpiezas); 

    for(int i = 0; sizeof(vpiezas)/sizeof(struct fichpiezas); i++){ 
     printf("Codigo pieza : %d\n", vpiezas[i].codPieza); 
    } 

    return 0; 
} 


int leer_fichero (struct fichpiezas *vpiezas[]){ 

    FILE *fich; 
    struct fichpiezas pieza; 
    int error_dev = 0, i = 0; 
    if ((fich = fopen("piezas.bin", "rb")) == NULL){ 
     printf ("Error en apertura del fichero para lectura \n "); 
     error_dev = 1; 
    } else{ 
     //Bucle mientras no sea fin de fichero 
     while (! feof(fich)){ 
      fread (&pieza, sizeof(pieza), 1, fich); 
      vpiezas[i] = &pieza; 
      i++; 
     } 

     fclose (fich); 
    } 

    return error_dev; 
} 
+1

код/​​комментарии на английском языке, как правило, упрощается чтение, но 'pieza' в 'leer_fichero' имеет локальное хранилище, и вы просто продолжаете помещать этот адрес в свой массив, и этот объект будет недоступен после завершения функций. – crashmstr

+0

Эта строка: 'for (int i = 0; sizeof (vpiezas)/sizeof (struct fichpiezas); i ++) {' в main() имеет проблему. он никогда не выходит из цикла for, потому что вычисление всегда одно и то же. предположим: 'for (int i = 0; i <(sizeof (vpiezas)/sizeof (struct fichpiezas)); i ++) {' Примечание: значение вычисления всегда будет «TAM» – user3629249

+0

: 'while (! feof (fich)) {'не будет работать так, как ожидалось, потому что feof() не определяется до тех пор, пока операция чтения из файла fich не предложит использовать:' while (fread (& pieza, sizeof (pieza), 1, fich)) 'fread вернет третий параметр при успехе и (в этом случае) 0, когда произойдет сбой/EOF. – user3629249

ответ

4

Просто изменить

int leer_fichero (struct fichpiezas *vpiezas[]) 

в

int leer_fichero (struct fichpiezas *vpiezas) 

и в вашей main()

leer_fichero(&vpiezas); 

к

leer_fichero(vpiezas); 

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

У вас есть еще одна проблема, это назначение

vpiezas[i] = &pieza; 

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

Aditionally значение pieza будет перезапись в каждой итерации бушель fread() и так как вы храните адрес pieza вместо его значение, все элементы массива будут иметь такое же значение, если это удалось таким образом.

Вам нужно скопировать-структуру в элемент массива, и эта линия, если вы будете следовать моим советам выше должен измениться

vpiezas[i] = pieza; 

или программа не будет компилироваться, так как тип &pieza является struct fichpiezas * и то vpiezas[i] теперь struct fichpiezas после смены прототипа функции.

Также около while (! feof(fich)) был answer, который подробно объясняет, почему это неправильно.

И еще одно, добавьте чек i < TAM, потому что вы рискуете переполнять массив в противном случае.

Nota: Espero ser de ayuda.

+2

или 'int leer_fichero (struct fichpiezas vpiezas [])' – Barmar

+0

Спасибо! Я собираюсь это доказать. – abemart

3

Это

int leer_fichero(struct fichpiezas * vpiezas[]); 

определяет vpiezas быть указателем на указатель на struct fichpiezas как

int leer_fichero(struct fichpiezas * vpiezas[]); 

эквивалентно

int leer_fichero(struct fichpiezas ** vpiezas); 

Для решения элементов массива вы пройти, сделав

leer_fichero(&vpiezas); 

нравится этот

(*vpiezas)[index] 

внутри leer_fichero().


Было бы более прямо вперед, чтобы определить

int leer_fichero(struct fichpiezas * vpiezas); 

и передать

leer_fichero(vpiezas); 

, то вы можете обратиться к элементам, как и вы:

vpiezas[index] 
+0

'int leer_fichero (struct fichpiezas * vpiezas []);' не "определяет' vpiezas' как указатель на указатель на 'struct fichpiezas'. Он определяет 'vpiezas' быть (используется в функции as) массив указателей на' struct fichpiezas'. В противном случае ваше решение будет работать, но ваше первое предложение будет более четким, если вы также предложили изменить определение функции на 'int leer_fichero (struct fichpiezas (* vpiezas) []);' или просто 'int leer_fichero (struct fichpiezas ** vpiezas); ', для ясности, при использовании' (* vpiezas) [index] 'для доступа. – kavadias

+0

@kavadias: см. Мой обновленный ответ, особенно обратите внимание, что в контексте определения параметров функции в C 'char []' эквивалентно 'char *', а также 'char * []' эквивалентно 'char ** '... – alk

+0

@kavadias: Также обратите внимание, что любой массив, переданный функции, распадается на указатель на 1-й элемент. – alk

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