Thread: How to save array to file

  1. #1
    Registered User
    Join Date
    Dec 2014
    Posts
    25

    How to save array to file

    There is a simple C-code, where I defined array of string type. Need to save it into ASCII-file (later I will need to read array back from this file). I know that I did something wrong in 'fwrite'. Please help me to find the problem and fix it.

    Code:
    #include <stdio.h>
    #include <string.h>
    
    
    char* a[2]      = {"130123456789", "2"};
    
    
    int main(int argc, char* argv[]) {
    
        printf("\n a[0] = %s", a[0]);
        printf("\n a[1] = %s", a[1]);
    
    
    // ====================================================
    
        FILE *file_01;
    
        if((file_01   = fopen("OUT_a.txt","w"))==NULL) {
            printf("CANNOT OPEN FILE OUT_a.txt 'w'\n");
            exit(1);
        };
    
    
        printf("\n strlen(a[0]) = %i", strlen(a[0]));
        printf("\n strlen(a[1]) = %i", strlen(a[1]));
    
    
        int t1 = fwrite(*a, (strlen(a[0])+strlen(a[1])), 1, file_01);
    
        printf("\n t1 = %i", t1);
    
        fclose(file_01);
    
    // ====================================================
    
        printf("\n\nFINISH!\n");
    
        return 0;
    }

  2. #2
    Registered User
    Join Date
    Dec 2017
    Posts
    1,633
    a is an array of two pointers and you are writing 13 bytes starting at the first pointer. If the pointers are 8 bytes each, you are writing the first 13 bytes of the pointer values. If they are 4 byte pointers then you are writing all 8 bytes of the two pointers plus 5 bytes of whatever happens to be directly after them in memory. You are not writing the strings at all (unless you have 4-byte pointers and part of the strings are in those 5 extra bytes).

    Normally you don't use fwrite to write to a text file. fprintf is more usual.
    Code:
    fprintf(file_01, "%s\n%s\n", a[0], a[1]);
    A little inaccuracy saves tons of explanation. - H.H. Munro

  3. #3
    Registered User
    Join Date
    Dec 2014
    Posts
    25
    Quote Originally Posted by john.c View Post
    a is an array of two pointers and you are writing 13 bytes starting at the first pointer. If the pointers are 8 bytes each, you are writing the first 13 bytes of the pointer values. If they are 4 byte pointers then you are writing all 8 bytes of the two pointers plus 5 bytes of whatever happens to be directly after them in memory. You are not writing the strings at all (unless you have 4-byte pointers and part of the strings are in those 5 extra bytes).

    Normally you don't use fwrite to write to a text file. fprintf is more usual.
    Code:
    fprintf(file_01, "%s\n%s\n", a[0], a[1]);
    I found the following example in the internet:

    Code:
    int main()
    {
        std::string array[] = { "S1", "S2", "S3" };
        std::cout << "A number of elements in array is: "
                  << sizeof(array)/sizeof(array[0]) << '\n';
        foo(array);
    }

    The most interesting to me is the following line:

    Code:
    string array[] = { "S1", "S2", "S3" };
    I tried to use 'string array[]...', but my compiler DevC++ didn't accept it. Maybe you know why?

  4. #4
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    That's C++ code, not C.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  5. #5
    Registered User
    Join Date
    Dec 2014
    Posts
    25
    Quote Originally Posted by john.c View Post
    a is an array of two pointers and you are writing 13 bytes starting at the first pointer. If the pointers are 8 bytes each, you are writing the first 13 bytes of the pointer values. If they are 4 byte pointers then you are writing all 8 bytes of the two pointers plus 5 bytes of whatever happens to be directly after them in memory. You are not writing the strings at all (unless you have 4-byte pointers and part of the strings are in those 5 extra bytes).

    Normally you don't use fwrite to write to a text file. fprintf is more usual.
    Code:
    fprintf(file_01, "%s\n%s\n", a[0], a[1]);

    Somebody helped me with this code, now saving array to file works. I added second part - read array from file - compiler complained that something is wrong. Maybe you know where is mistake?


    Code:
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    
    char* a[2]                   = {"0123456789", "2"};
    
    
    int main(int argc, char* argv[]) {
    // ====================================================
    
        FILE *file_01;
    
        if((file_01               = fopen("OUT_a.txt","w"))==NULL) {
            printf("CANNOT OPEN FILE OUT_a.txt 'w'\n");
            exit(1);
        };
    
    
        for (size_t i=0; i<(sizeof(a)/sizeof(a[0])); i++) {
          fwrite(a[i], 1, strlen(a[i]) + 1, file_01);
        }
    
    
        fclose(file_01);
    // ====================================================
    
     
     
    // ====================================================
     
        if((file_01               = fopen("OUT_a.txt","r"))==NULL) {
            printf("CANNOT OPEN FILE OUT_a.txt 'r'\n");
            exit(1);
        };
     
     
        int  x0                   = sizeof(a)/sizeof(a[0]);
        char* b[x0];
     
     
        printf("\n");
        printf("\n (sizeof(b)/sizeof(b[0]))    = %i", (sizeof(b)/sizeof(b[0])) );            // [bytes]
     
     
        int i2                    = 0;
     
        while(fscanf(b[i2], "%s", file_01) != EOF) {
            printf("\n%s", b[i2]);
            i2++;
        }
     
    
     
        fclose(file_01);
    // ====================================================
     
    
        printf("\n\nFINISH!\n");
     
     
        return 0;
    }

  6. #6
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Don't do this:
    Code:
    char* a[2]                   = {"0123456789", "2"};
    You declared a at file scope, making it a global variable, and then gave it a name that is not descriptive. Furthermore, you failed to use const, yet arranged for the pointers to point to string constants, risking undefined behaviour. I would suggest something like this:
    Code:
    int main(void) {
        const char *const output[] = {"0123456789", "2"};
    I declared what the pointers point to as const because they will point to string constants, then I declared the pointers themselves as const because you never modify this, and don't seem to need to. If you have more context as to what this output is about, it would be better to use that in the name instead of the more generic name of "output".

    Next, as john.c noted in post #2, you wouldn't normally use fwrite to write, so I would change this:
    Code:
    fwrite(a[i], 1, strlen(a[i]) + 1, file_01);
    to:
    Code:
    fprintf(file_01, "%s\n", output[i]);
    If you really want to use fwrite, it can be done, but then you need to know the string length in advance (i.e., typically this means writing fields of equal length, e.g., by writing a fixed size array, or a struct containing a fixed size array), which is impossible with the file format that you came up with.

    Having made these changes, we can move on to your read portion. You should be aware that this creates a variable length array:
    Code:
    int  x0                   = sizeof(a)/sizeof(a[0]);
    char* b[x0];
    The variable length array feature was standardised in the 1999 edition of the C standard, but later became optional, so you should not use it unless you are sure of your code being compiled by a compiler that supports that language feature. Yet, you don't need a variable length array here. You could have written:
    Code:
    char *input[sizeof(output) / sizeof(output[0])];
    Now, input is a fixed size array. But... you have another problem: you don't have any space allocated for the strings themselves, and you cannot know how much space needs to be allocated without first reading from file, so it is a bit of a chicken and egg scenario.

    For convenience, I suggest that you assume that there's a known upper bound to the length of the input strings, then arrange for arrays of char to be of that upper bound. For example, you could use BUFSIZ from <stdio.h>:
    Code:
    char input[sizeof(output) / sizeof(output[0])][BUFSIZ];
    Having done that, you can now do what you planned:
    Code:
    while (fscanf(file_01, "%s", input[i2]) == 1) {
        printf("%s\n", input[i2]);
        i2++;
    }
    Note that this is technically vulnerable to buffer overflow: we should construct the format string such that the %s format specifier has a field width corresponding to the upper bound of the length of the input strings.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  7. #7
    Registered User
    Join Date
    Dec 2014
    Posts
    25
    Quote Originally Posted by laserlight View Post
    Don't do this:..
    Thank you for your reply!
    Unfortunately I didn't get an email notification, so I read it just now.
    I will modify the code based on your suggestions.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. save a spicific column from a csv file into an array
    By Tasneem Gamal in forum C Programming
    Replies: 5
    Last Post: 09-07-2017, 11:57 AM
  2. Replies: 0
    Last Post: 03-21-2013, 03:31 PM
  3. Replies: 1
    Last Post: 03-19-2009, 10:56 AM
  4. Open File/Save File crashes on cancel?
    By Blackroot in forum Windows Programming
    Replies: 0
    Last Post: 08-02-2008, 02:16 AM
  5. Save array
    By eletron in forum C Programming
    Replies: 3
    Last Post: 02-24-2005, 03:47 PM

Tags for this Thread