-1

I have to use the function to open a file, read it, save the first value as the number of following elements (dimension) and the other values in the seq[] array. I don't know how to return both dimension and seq[] in the main; I need it because I have to use these values in other functions. As the code shows, the function returns the dimension (dim), but I don't know how to return the array.

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>

int leggiSequenza(char *nomeFile, int *seq) {

FILE *in;
int i;
int dim;

if((in = fopen(nomeFile, "r"))==NULL) {
    printf("Error.\n");
    return -1;
}

fscanf(in, "%d", &(dim));
printf("Find %d values.\n", dim);

if(dim < 0) {
    printf("Errore: negative value.\n");
    return -1;
}

seq = (int*) malloc(dim*sizeof(int));

i=0;
while(!feof(in) && i<(dim)) {
    fscanf(in, "%d", &seq[i]);
    i++;
}

for(i=0; i<(dim); i++) {
    printf("Value in position number %d: %d.\n", i+1, seq[i]);
}

free(seq);
fclose(in);

return dim;
}


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

int letturaFile;
char nomeFile[200];
int *dimensione;

printf("Insert file name:\n");
scanf("%s", nomeFile);
printf("\n");
letturaFile = leggiSequenza(nomeFile, dimensione);
dimensione = &letturaFile;
printf("dimension = %d\n", *dimensione);

return 0;
}

I think the focus of the problem is *seq; I have to return two values (dimension and array). Moreover, I can't edit the parameters of the function.

I think my question is different from this because in my function there is a parameter with a pointer, and the function hasn't got a pointer...

Community
  • 1
  • 1
FranzGoogle
  • 451
  • 3
  • 5
  • 14
  • You need to read [this](http://stackoverflow.com/questions/5431941/why-is-while-feof-file-always-wrong) – Ed Heal Jan 24 '17 at 22:28

3 Answers3

1

Change the function to take the array pointer by pointer:

int leggiSequenza(char *nomeFile, int **seq);
//                                ^^^^^^^^^

Then call it with the address of your variable:

leggiSequenza(nomeFile, &dimensione);
//                      ^^^^^^^^^^^

Inside the function definition, change the details around like so:

int leggiSequenza(char *nomeFile, int **seq) {
  // ...
  int *local_seq = malloc(dim*sizeof(int));

  // use local_seq in place of seq

  // free(local_seq);   // delete ...
  *seq = localsec;      // ... and replace with this

  return dim;
}

Finally, the caller needs to free the array:

free(dimensione);


Update: Since you've re-asked your question: Pre-allocate the memory at the call site:

int * p = malloc(200 * sizeof(int));

int dim = leggiSequenza(filename, p);

// ...

free(p);
Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
  • Thank you, I also thought this kind of solution. But it's a text from an exercise and I suppose it's resolvable with the original parameter... – FranzGoogle Jan 24 '17 at 22:30
  • @FranzGoogle: Then preallocate the storage at the call site. – Kerrek SB Jan 24 '17 at 22:40
  • I'm sorry, I'm quite new in programming. Can I preallocate the storage in the main if I have to open the file in the function? I can't know 'a priori' the contents of the file. Or not? – FranzGoogle Jan 24 '17 at 22:46
  • @FranzGoogle: Well, indeed, you'll need to agree on a maximal tolerable size and not read more than that from the file. Otherwise you need to reorganize your code a bit to support truly dynamic behaviour. – Kerrek SB Jan 24 '17 at 22:48
  • I'm confused. Let's suppose I prealloc an array in the main. Now, how can I link the array in the function with my preallocated array? – FranzGoogle Jan 24 '17 at 22:57
  • @FranzGoogle: You just pass the address of the array's first element as the second function argument! – Kerrek SB Jan 24 '17 at 22:57
  • Do you refer to `*seq = localsec`? I know I'm dumb, but I can't understand where I have to pass it. I have to consider your first post still valid? – FranzGoogle Jan 24 '17 at 23:06
  • @FranzGoogle: I redid the answer, I hope this is clearer. – Kerrek SB Jan 24 '17 at 23:15
  • OK, it's clear. I'm not fully convinced about the preallocation with `200`, but I think it's the best solution. Thank you for your help and patience! – FranzGoogle Jan 24 '17 at 23:45
  • @FranzGoogle: Right, that's why in real life you'd have code like in my original answer. The problem setting is a bit silly. – Kerrek SB Jan 24 '17 at 23:58
0

Simply your function should have this signature

int leggiSequenza(char *nomeFile, int **seq)

and when passing the parameter to it you should do

letturaFile = leggiSequenza(nomeFile, &dimensione);

that way, you'll have both things. Also, everywhere in your function where you have just seq , you need to add *seq so you can dereference the pointer.

Hope this helps!

kantagara
  • 120
  • 2
  • 10
0

Do the alloction of the array in the main function

 int *dimensione; = (int*) malloc(200*sizeof(int));

then delete this line

free(seq);

and you should have the data in the array in the main function.

Alex
  • 779
  • 7
  • 15
  • OK, but I waste memory in this way... Or not? – FranzGoogle Jan 24 '17 at 22:34
  • @FranzGoogle correct, i forget. You have to add `free(dimensione);` in the main function. – Alex Jan 24 '17 at 22:36
  • @FranzGoogle , here is the codesnippet: `printf("dimension = %d\n", *dimensione); free(dimensione); return 0;` – Alex Jan 24 '17 at 22:38
  • I have to keep the malloc in the function? And how it can help me to use the `seq[]` array? – FranzGoogle Jan 24 '17 at 22:43
  • @FranzGoogle, dimensione will be given as a paramter to leggiSequenza as a pointer to int type from the main function. Then in the function leggiSequenza this is the pointer seq to the first element of the dimensione array, you can use it the way you already do. the malloc has to happen in the main function, because, at the end of leggiSequenza function, the local allocated memory would go out of scope. – Alex Jan 24 '17 at 22:50