Массив, проходящий в C

У меня проблема с передачей массива функции в C. Я объявляю массив в основном

И затем, внутри функции, я заполняю ее.

В этот момент я оставляю свою функцию и передаю массив другой функции с прототипом

И попытаемся получить доступ к массиву.

Однако, как только я выхожу из начальной функции, заполняющей массив, я не могу получить доступ к массиву. Он просто возвращает значения 0.00000 и nan.

void ReadData(FILE *fpIn, int lines, double *pA );
void MinMaxAvg(double *pA, double *min, double *max, double *avg, int lines);

int main()
{
    FILE *fpIn = NULL;

    int lines = 0;

    double *pA = NULL;

    ReadData(fpIn, lines, pA);

    double min = 0;
    double max = 0;
    double avg = 0;

    MinMaxAvg(pA, &min, &max, &avg, lines);

    printf("%lf %s %lf %s %lf \n", avg, " ", min, " ", max);

    return 0;
}   

void ReadData(FILE *fpIn, int lines, double *pA )
{
    char fName[20];
    scanf( "%s", fName);

    fpIn = fopen ( fName, "rt");
// fpIn = fopen( "test1.txt", "rt");

    if ( fpIn == NULL)
    {
        printf( "Unable to open: ");
        exit(99);
    }

//Gets Lines

//int lines=0;
    char ch;

    while((ch=fgetc(fpIn))!=EOF)
    {
        if (ch=='\n') { lines++; }

    }

// clearerr(fName *fpIn);
    fclose(fpIn);
    fopen(fName, "rt");

//Makes Array

//double *pA;

    pA = (double *)malloc(lines*sizeof(double));

//Fills Array

    for (int i=0; i *max)
            {
                *max = pA[i];
            }
        }

        total += pA[i];

    }

    *avg = (total/(double)lines);

}

Какие-либо предложения?

Благодаря!

0
nl ja de
Это не массив, это указатель. Кроме того, как вы «оставите свою функцию»? Вы return pA ?
добавлено автор Fred Foo, источник
Это указатель на массив. И никакая функция не является пустой. Я передаю массив по ссылке так же, как и в функции MinMaxAvg. Это сработало отлично, прежде чем я попытался выделить массив в первой функции ...
добавлено автор aprohl5, источник
Что бы вы хотели посмотреть? Я могу добавить к вопросу.
добавлено автор aprohl5, источник
Это все там сейчас :)
добавлено автор aprohl5, источник
Что я должен превращать в fpIn = ...? Fopen после fclose или fpIn в fscanf?
добавлено автор aprohl5, источник
В ReadData у вас есть fclose (fpIn); fopen (fname, "rt"); , после чего вы вызываете fscanf (fpIn, ...) . Нет причин полагать, что второй fopen возвращает тот же самый указатель, что и первый. Сделайте это fpIn = fopen (fname, "rt"); и снова проверьте NULL .
добавлено автор Daniel Fischer, источник
А затем исправьте распределения min и max (т. Е. Добавьте их). Покажите, где переменные, переданные как min и max , объявлены . У вас есть pA декларация, добавьте остальные в PLZ.
добавлено автор WhozCraig, источник
Я не вижу здесь ничего плохого. Это должно быть что-то в той части, которую вы нам не показываете.
добавлено автор KBart, источник
Ваша основная функция, где вы объявляете параметры и вызываете отображаемые функции.
добавлено автор KBart, источник
Оставьте весь код в одном блоке.
добавлено автор user1944441, источник

3 ответы

Вы подсчитали количество строк в файле в локальной переменной «lines» в функции ReadData (), но это не значит, что оно возвращается к основному. Значение переменной «lines», которое передается в MinMaxAvg (), равно нулю.

3
добавлено
Мне нравится идея об этом, но как только я реализую ее, остальная часть кода ломается. Я неожиданно не могу пройти мимо scanf («% s», fName); он держится за мной. Я не знаю, как эти два влияют друг на друга, хотя ...
добавлено автор aprohl5, источник
Спасибо. Я действительно пошел с маршрутом перемотки (fpIn), но я буду держать метод fseek() в виду для будущего использования.
добавлено автор aprohl5, источник
Как писал Даниил Фишер выше, нет хорошей идеи: fclose (fpIn); fopen (fName, "rt"); ... ch = fgetc (fpIn); Вместо этого попробуйте: fseek (fpIn, 0L, SEEK_SET);
добавлено автор oleg_g, источник

Основываясь на том, что у вас есть в ваших вопросах, если вы заполняете pA в функции, я подозреваю, что вы не меняете содержимое pA, что может быть проблемой. Может быть полезно/полезно увидеть рутину, которую вы используете для заполнения pA.

Функции C вызывают по значению, если вы просто передаете указатель (просто pA), чтобы изменить значение указателя, вам нужно передать адрес указателя (указатель на указатель, если хотите). Затем вам нужно поклониться, чтобы установить указатель (на указатель), а затем поместить его дважды, чтобы установить значения в выделенной памяти/массиве.

Таким образом, вызов функции

void init(File *fpin, double **pA, int lines)
{
  /* Deference once to set the pointer to the pitner */
  *pA = (double *)malloc(lines*sizeof(double));

  for (int i=0; i

а затем, вызывая процедуру, вам необходимо передать адрес pA.

init(fpIn,&pA,lines);

Here is a link which might help explain pointers to pointers: http://www.thegeekstuff.com/2012/01/advanced-c-pointers/

Прошло много времени с тех пор, как я сделал указатели на указатели, но если вы используете вышеизложенное, возможно, вам придется внести некоторые незначительные изменения.

Как намекает ларсманс, мне нравится его предложение об изменении подпрограммы, чтобы вернуть указатель на выделенную память и поместить это значение в pA.

double* init(File *fpin, int lines)
{
  double *local = (double *)malloc(lines*sizeof(double));

  //Fills Array

  for (int i=0; i

}

а затем в вызове init

pA = init(fpIn,lines);

В зависимости от того, чего вы пытаетесь достичь, это может быть легче понять и не так сложно.

1
добавлено

I have just tested your code and it works. The only difference i made is stdin in fscanf and have included max,min,avg and lines.

#include 
#include 


void MinMaxAvg(double *pA, double *min, double *max, double *avg, int lines)
{
    double total = 0;

    for (int i=0; i *max)
        {
        *max = pA[i];
        }
    }

    total += pA[i];

    }

    *avg = (total/(double)lines);

return;
}



int main(int argc, char** argv)
{
    double *pA = NULL;

    int lines = 3;

    double min,max,avg;

    pA = (double *)malloc(lines*sizeof(double));

    //Fills Array

    for (int i=0; i
0
добавлено
Ну да, он отлично работает, если вы выделите массив в основном. Я столкнулся с проблемой, когда я выделяю массив в функции ReadData ().
добавлено автор aprohl5, источник