fwrite can't write dynamic strings???

This is a discussion on fwrite can't write dynamic strings??? within the C Programming forums, part of the General Programming Boards category; Originally Posted by matsp Also, "od" works well for inspecting binary files - it supports printing in various display formats ...

  1. #16
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,047
    Quote Originally Posted by matsp View Post
    Also, "od" works well for inspecting binary files - it supports printing in various display formats (e.g. octal, hex, decimal, float(? Never used that)) as well as showing records of various lengths.

    --
    Mats
    yes od and xd work better than the xxd command of vi

  2. #17
    * Death to Visual Basic * Devil Panther's Avatar
    Join Date
    Aug 2001
    Posts
    768
    So my best solution is a staticly sized string?
    "I don't suffer from insanity but enjoy every minute of it" - Edgar Allen Poe

    http://www.Bloodware.net - Developing free software for the community.

  3. #18
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    21,725
    Quote Originally Posted by Devil Panther
    So my best solution is a staticly sized string?
    I am not sure about best, but it is a solution.

    Incidentally, have you considered say, using SQLite? It has been described by its own author as a substitute for fopen(), and depending on your requirements it could suitably do just that.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  4. #19
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,047
    Quote Originally Posted by Devil Panther View Post
    So my best solution is a staticly sized string?
    What's wrong with the dynamic solution? It works just as well.

  5. #20
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by itCbitC View Post
    What's wrong with the dynamic solution? It works just as well.
    Depending on what you are doing, it may make the whole scheme a lot more complex - for example, reading a variable size record can be quite a lot more complex than a fixed size one - either we need to store the size and then read back the size again to know how much more to read. Or if we don't store the size, we need to read each byte, until we get a zero.

    A struct like this:
    Code:
    struct 
    {
        int x;
        char *name;
        double d;
    };
    would require at least three writes and possibly almost indefinite number of reads, or four writes and four reads. [We could change the struct to hold a length as well, which would remove one read operation, as we read the length and x in the same operation].

    It gets even more messy if there are several strings in the structure.

    The other problem comes if we need to seek to get to element n. If each struct is stored with a different number of bytes, we can't actually use seek, unless we also keep a table of index -> offset. Or we have to read each element from first to whichever we look for.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  6. #21
    * Death to Visual Basic * Devil Panther's Avatar
    Join Date
    Aug 2001
    Posts
    768
    Quote Originally Posted by matsp View Post
    Depending on what you are doing, it may make the whole scheme a lot more complex - for example, reading a variable size record can be quite a lot more complex than a fixed size one - either we need to store the size and then read back the size again to know how much more to read. Or if we don't store the size, we need to read each byte, until we get a zero.

    A struct like this:
    Code:
    struct 
    {
        int x;
        char *name;
        double d;
    };
    would require at least three writes and possibly almost indefinite number of reads, or four writes and four reads. [We could change the struct to hold a length as well, which would remove one read operation, as we read the length and x in the same operation].

    It gets even more messy if there are several strings in the structure.

    The other problem comes if we need to seek to get to element n. If each struct is stored with a different number of bytes, we can't actually use seek, unless we also keep a table of index -> offset. Or we have to read each element from first to whichever we look for.

    --
    Mats
    I have the name length, see my struct.
    But when I write the char *name to the file it writes the pointer's address (as it should). How can I write the string itself?
    "I don't suffer from insanity but enjoy every minute of it" - Edgar Allen Poe

    http://www.Bloodware.net - Developing free software for the community.

  7. #22
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by Devil Panther View Post
    I have the name length, see my struct.
    But when I write the char *name to the file it writes the pointer's address (as it should). How can I write the string itself?
    Something like this:
    Code:
    struct stuff {
    	int nameSize;
    	char *name;
    	int num;
    };
    
    ...
    void writestuff(FILE *f, stuff *st)
    {
        fwrite(&st->nameSize, 1, sizeof(st->nameSize), f);
        fwrite(st->name, 1, st->nameSize, f);
        fwrite(&st->num, 1, sizeof(st->num), f);
    }
    And to read it, just do the same the other way around.

    [Note that I've assumed that nameSize includes the terminating zero. If it doesn't, you have to add one to it when reading and writing]

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  8. #23
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,047
    Quote Originally Posted by matsp View Post
    Depending on what you are doing, it may make the whole scheme a lot more complex - for example, reading a variable size record can be quite a lot more complex than a fixed size one - either we need to store the size and then read back the size again to know how much more to read. Or if we don't store the size, we need to read each byte, until we get a zero.
    Don't quite follow this part you posted. IMO, sizeof struct stuff will remain constant irrespective of the size of each dynamically allocated string its member name is pointing to. In this case struct stuff is defined as
    Code:
    struct stuff
    {
            int nameSize;
            char *name;
            int num;
    };
    and it doesn't matter if name points to a 100 element array of char or just one, the size of stuff will still be 12.
    Quote Originally Posted by matsp View Post
    A struct like this:
    Code:
    struct 
    {
        int x;
        char *name;
        double d;
    };
    would require at least three writes and possibly almost indefinite number of reads, or four writes and four reads. [We could change the struct to hold a length as well, which would remove one read operation, as we read the length and x in the same operation].

    It gets even more messy if there are several strings in the structure.
    Why so? Assuming 3 struct stuffs were created initially, it'll require 3 fwrite()s to store and exactly 3 fread()s to retrieve all of 'em.
    Quote Originally Posted by matsp View Post
    The other problem comes if we need to seek to get to element n. If each struct is stored with a different number of bytes, we can't actually use seek, unless we also keep a table of index -> offset. Or we have to read each element from first to whichever we look for.

    --
    Mats
    IBTD, each struct will be exactly the same size as even those "different number of bytes" aren't stored in the struct but are being pointed to by name. 'Tis the same whether the struct members are statically or dynamically allocated arrays.

  9. #24
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    21,725
    Quote Originally Posted by itCbitC
    Don't quite follow this part you posted. IMO, sizeof struct stuff will remain constant irrespective of the size of each dynamically allocated string its member name is pointing to.
    That is precisely the point: if a fixed size array is used, taking the sizeof the struct will reflect the array size. If a dynamic array is used, then the part about storing the size or using a designated termination value comes into play. In such a case, when we talk about the size of the record, we are not talking about taking the sizeof the struct, but about the size including the dynamic array that is involved.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  10. #25
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,185
    Quote Originally Posted by itCbitC View Post
    Don't quite follow this part you posted. IMO, sizeof struct stuff will remain constant irrespective of the size of each dynamically allocated string its member name is pointing to. In this case struct stuff is defined as
    Code:
    struct stuff
    {
            int nameSize;
            char *name;
            int num;
    };
    and it doesn't matter if name points to a 100 element array of char or just one, the size of stuff will still be 12.

    Why so? Assuming 3 struct stuffs were created initially, it'll require 3 fwrite()s to store and exactly 3 fread()s to retrieve all of 'em.

    IBTD, each struct will be exactly the same size as even those "different number of bytes" aren't stored in the struct but are being pointed to by name. 'Tis the same whether the struct members are statically or dynamically allocated arrays.
    Except that all you're going to write is a pointer, which will provide zero actual data. You need to follow the data and write what it points to, which could be who knows how big.

  11. #26
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,047
    Quote Originally Posted by laserlight View Post
    That is precisely the point: if a fixed size array is used, taking the sizeof the struct will reflect the array size. If a dynamic array is used, then the part about storing the size or using a designated termination value comes into play. In such a case, when we talk about the size of the record, we are not talking about taking the sizeof the struct, but about the size including the dynamic array that is involved.
    gotcha!

  12. #27
    * Death to Visual Basic * Devil Panther's Avatar
    Join Date
    Aug 2001
    Posts
    768
    Thank you for all your help
    "I don't suffer from insanity but enjoy every minute of it" - Edgar Allen Poe

    http://www.Bloodware.net - Developing free software for the community.

Page 2 of 2 FirstFirst 12
Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 2
    Last Post: 04-29-2009, 10:13 AM
  2. Help with calloc and pointers to strings.
    By sweetarg in forum C Programming
    Replies: 1
    Last Post: 10-24-2005, 02:28 PM
  3. operator overloading and dynamic memory program
    By jlmac2001 in forum C++ Programming
    Replies: 3
    Last Post: 04-06-2003, 11:51 PM
  4. Dynamic Toolbars
    By nvoigt in forum Windows Programming
    Replies: 1
    Last Post: 01-11-2002, 09:21 AM
  5. array of strings + more
    By null in forum C Programming
    Replies: 10
    Last Post: 10-01-2001, 03:39 PM

Tags for this Thread


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21