0

I'm writing an exercise on C. I have a struct "testo" with an array of strings and an int.

typedef struct{
char** f;
int n;  }testo;

I have to write a function like this: int carica(char*,testo*) where the string is the name of a file with this format:

n
strin1
...
string n

Then I have to allocate memory for this struct and put every string of the file in the struct so in the end it should be that f[j] is "string j". The return is 0 if everything worked fine or -1,-2,-3,-4 depending on the error that occurs. My function works but then in main it's like I haven't filled the struct.

There is my code:

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

typedef struct{
    char** f;
    int n;
}testo;

int carica(char*,testo*);

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

    testo* txt;
    carica("prova.txt",txt);

    //mostra(txt);

    return 0;
}

int carica(char* nf,testo* txt){
    FILE* file;
    if( (file = fopen(nf,"r") )==NULL){
        return -1;
    }
    int n_of_strings;
    if(fscanf(file,"%d",&n_of_strings)==EOF || n_of_strings<1){
        return -2;
    }

    getc(file);

    txt = malloc(sizeof (testo) );
    if (txt==NULL)
        return -3;
    txt->n = n_of_strings;
    txt->f = malloc(sizeof(char)*BUFSIZ*n_of_strings);

    char aux[BUFSIZ];

    for(int i=0; i<n_of_strings; i++){
        for(int j=0; aux[j]!='\0';j++)
            aux[j] = '\0';
        fgets(aux,BUFSIZ,file);
        txt->f[i] = malloc(strlen(aux));
        if ((txt->f[i])==NULL)
            return -4;
        strcpy(txt->f[i],aux);
    }
    fclose(file);
    return 0;
}

1 Answers1

0

When you call carica from main, you are just passing the value of txt, which has not yet been initialized. txt is a pointer to a testo, but what you want is a pointer to a pointer to a testo. You can get this using the & (address of) operator, e.g. &txt.

The carica function also needs to be changed to: int carica(char* nf, testo** txt) (note the extra *). Then, when you want to write to txt, you need to use *txt instead. This dereferences the pointer and allows you to write directly into main's local variable txt.

David Alexander
  • 659
  • 1
  • 4
  • Thank you so much. Just to be sure I totally understand it: my mistake was that I send in my function carica a pointer to a structure, in the function I change what that pointer point at with malloc function but then i return a int so the change I made on the pointer is lost. Your solution is sending the pointer of that pointer so I modify what there is in the thing pointed but not the pointer, so it still point to the same thing, but that thing has changed values. Am i right? – Davide Marchesi Jun 08 '22 at 14:11
  • Yes, that's correct. When you pass a parameter to a function, really the function gets a "copy" of the thing that you passed. The function can modify the copy without affecting the original. This is true even if the thing being passed is a pointer - the **pointer** itself will be copied, and changing the copy will not affect the original. But what you *can* do with a pointer, is change **the thing that it points to** (which, in this case, is itself **another pointer**). – David Alexander Jun 09 '22 at 01:34
  • Another way of saying this is that C always uses "pass-by-value" semantics (except for arrays, which automatically get passed as pointers), meaning that whenever you pass a parameter, only its value gets passed, not an actual reference to it. Other languages may have different semantics, for example C++ allows function parameters to be declared as pass-by-reference. Many higher-level languages use pass-by-value for primitive types, and pass-by-reference for non-primitive types. – David Alexander Jun 09 '22 at 01:40