Thread: Write dynamic structure to a text file

  1. #1
    Registered User
    Join Date
    May 2012
    Posts
    5

    Write dynamic structure to a text file

    Hey guys,

    I'm having some problem writing a dynamic structure to a text file. The fact is that I already did the function for reading from the text file to the structure, but I'm trying hard and I can't do the opposite.

    So, I have this structure here:
    Code:
    typedef struct ContaFicheiro {
        unsigned int numero;
        char nomeUtilizador[20];
        char PIN[5];
        float saldo;
    } ContaFicheiro;
    and the array of structures is declared as global variable (because it has to):

    Code:
    ContaFicheiro *arrayContas;
    And well, this is the function I wrote to write the data of the structure in a text file, called "accounts2.txt":
    Code:
    void escreveAccounts(ContaFicheiro *array, unsigned int ultimaConta) {
        FILE* fp;    
        int i;
        
        int tamanho = sizeof &array / sizeof &array[0];
    
        array = (ContaFicheiro *) malloc(sizeof(ContaFicheiro)*sizeof(array));
        
        if( (fp = fopen("accounts2.txt", "w")) != NULL) {
            fprintf(fp, "%u\n", ultimaConta);
            for(i = 0; i < tamanho; i++) {        
                //printf("Numero:%u\tNome:%s\tPIN:%s\tSaldo%f\n", array[i].numero, array[i].nomeUtilizador, array[i].PIN, array[i].saldo);             
                fprintf(fp, "%u\t%s\t%s\t%f\n", array[i].numero, 
                                array[i].nomeUtilizador, 
                                array[i].PIN, 
                                array[i].saldo);    
            }    
        }
        
        else {
            perror("\nFicheiro 'accounts.txt' nao existe, impossivel completar operacao com sucesso.");
        }
        
        free(array);
        fclose(fp);
    }
    The thing is that it doesn't print any information about the structure. Can you help me with this ?
    Last edited by deathseeker25; 05-22-2012 at 11:26 AM.

  2. #2
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Quote Originally Posted by deathseeker25 View Post
    and the array of structures is declared as global variable (because it has to):
    Please, tell me why "it has to" be global. 99% of the time, people coming here for help say they have to use globals, but they're wrong. Globals are almost always the wrong way to solve a problem. Declare them in the right scope/function and pass them around as necessary. Read this: Global Variables Are Bad.

    Code:
        int tamanho = sizeof &array / sizeof &array[0];
    
        array = (ContaFicheiro *) malloc(sizeof(ContaFicheiro)*sizeof(array));
    These size calculations are not what you want. sizeof &array is the size of a pointer to pointer to ContaFicheiro. sizeof &array[0] is the sizeof a pointer to ContaFicheiro. You can't get the size of an array unless you are in the same scope in which you declare it. I don't really know what you're trying to accomplish with the tamanho calculation, i.e. what you think those sizeof operations return, but it seems tamanho is the number of things you want in your array. The sizeof(ContaFicheiro) in your malloc call is the size of one element, sizeof(array) is the size of a pointer to a ContaFicheiro. The result of multiplying them is some useless number. Your malloc call should look something more like:
    Code:
    array = malloc(tamanho * sizeof(*array));
    Notice, I use *array in the sizeof. That is saying "size of the thing pointed to by array", or "size of one array element". You multiply that by the number of items you want for your array.

    Also, don't cast the return value of malloc. Read this: FAQ > Casting malloc - Cprogramming.com
    Code:
                fprintf(fp, "%u\t%s\t%s\t%f\n", array[i].numero, 
                                array[i].nomeUtilizador, 
                                array[i].PIN, 
                                array[i].saldo);
    The thing is that it doesn't print any information about the structure. Can you help me with this ?
    What data do you expect to be in the structure at this point? You allocated a bunch of memory (the malloc call), but never put any data in it.

  3. #3
    Registered User
    Join Date
    May 2012
    Posts
    5
    Quote Originally Posted by anduril462 View Post
    Please, tell me why "it has to" be global. 99% of the time, people coming here for help say they have to use globals, but they're wrong. Globals are almost always the wrong way to solve a problem. Declare them in the right scope/function and pass them around as necessary. Read this: Global Variables Are Bad.
    It has to be global because it's what's specified in the project sheet. This is a college project and there are some things I just have to follow, even though, after reading the article you suggested, I agree that yeah, global variables are quite bad.

    Quote Originally Posted by anduril462 View Post
    Code:
        int tamanho = sizeof &array / sizeof &array[0];
    
        array = (ContaFicheiro *) malloc(sizeof(ContaFicheiro)*sizeof(array));
    These size calculations are not what you want. sizeof &array is the size of a pointer to pointer to ContaFicheiro. sizeof &array[0] is the sizeof a pointer to ContaFicheiro. You can't get the size of an array unless you are in the same scope in which you declare it. I don't really know what you're trying to accomplish with the tamanho calculation, i.e. what you think those sizeof operations return, but it seems tamanho is the number of things you want in your array.
    So, how exactly can I know what's the size of the array *array ? I understand the tamanho calculations are not correct, but how will I know then the size of it so I can use it in the for cycle ?

    Quote Originally Posted by anduril462 View Post
    The sizeof(ContaFicheiro) in your malloc call is the size of one element, sizeof(array) is the size of a pointer to a ContaFicheiro. The result of multiplying them is some useless number. Your malloc call should look something more like:
    Code:
    array = malloc(tamanho * sizeof(*array));
    Notice, I use *array in the sizeof. That is saying "size of the thing pointed to by array", or "size of one array element". You multiply that by the number of items you want for your array.

    Also, don't cast the return value of malloc. Read this: FAQ > Casting malloc - Cprogramming.com

    What data do you expect to be in the structure at this point? You allocated a bunch of memory (the malloc call), but never put any data in it.
    At this point there is data in the structure, data that was read from a file exactly with the same string format to save data.

  4. #4
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Quote Originally Posted by deathseeker25 View Post
    It has to be global because it's what's specified in the project sheet. This is a college project and there are some things I just have to follow, even though, after reading the article you suggested, I agree that yeah, global variables are quite bad.
    Well, your professor is a dunderhead. You can even tell him I said so .

    So, how exactly can I know what's the size of the array *array ? I understand the tamanho calculations are not correct, but how will I know then the size of it so I can use it in the for cycle ?
    How am I supposed to know? It depends on the project specifications. Actually, your next question, and my answer, takes care of this issue.

    At this point there is data in the structure, data that was read from a file exactly with the same string format to save data.
    At that point, there is on longer data in the structure. You read it in from a file, passed a pointer to that data, then allocated new memory, with no data in it, and overwrote the pointer. You no longer have access to the data you read it, only to the newly allocated memory. If you already have the data in array, you don't need that malloc call at all. It also sounds like, if you already read the data, then you already know how many items in your array, so you could just pass tamanho in as a parameter, no need to calculate it. Or perhaps this is what the ultimaConta variable is for, and you don't even need tamanho.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. write structure to a file
    By tubby123 in forum C Programming
    Replies: 11
    Last Post: 07-02-2011, 11:20 AM
  2. How to write data from file to structure, This case is different.
    By TanzeelurRehman in forum C Programming
    Replies: 6
    Last Post: 12-22-2010, 11:34 PM
  3. Replies: 5
    Last Post: 03-18-2006, 11:25 AM
  4. Structure Dynamic with File Write
    By k4z1nh0 in forum C Programming
    Replies: 1
    Last Post: 06-25-2005, 11:46 AM
  5. Reading in from 1 file into 1 dynamic structure
    By ajax in forum C Programming
    Replies: 2
    Last Post: 07-22-2002, 02:40 AM