Sameh Shohdy
Sameh Shohdy

Reputation: 21

Store struct to file and retrieve it again

I have a struct as

typedef struct esl_sqfile_s {
  FILE *fp;           /* Open file ptr                            */
  char *filename;         /* Name of file (for diagnostics)           */
  int   do_gzip;          /* TRUE if we're reading from gzip -dc pipe */
  int   do_stdin;         /* TRUE if we're reading from stdin         */
  char  errbuf[eslERRBUFSIZE];/* parse error mesg. Size must match msa.h  */

  /* all input first gets buffered in memory; this gives us enough
   * recall to use Guess*() functions even in nonrewindable streams
   */
  char    *mem;           /* buffered input                           */
  int      allocm;        /* <mem> size, multiples of eslREADBUFSIZE  */
  int      mn;            /* number of chars in <mem> (up to allocm)  */
  int      mpos;          /* pos of next <buf> to load from <mem>     */
  off_t    moff;          /* disk offset to start of <mem>            */
  int      is_recording;      /* TRUE if we need to keep buffering more   */

  /* input is either character-based [fread()] or line-based (esl_fgets())*/
  char    *buf;           /* buffer for fread() or fgets() input      */
  off_t    boff;          /* disk offset to start of buffer           */
  int      balloc;        /* allocated size of buf                    */
  int      nc;            /* #chars in buf (usually full, less at EOF)*/ 
  int      bpos;          /* current position in the buffer (0..nc-1) */
  int64_t  L;             /* #residues seen so far in current seq     */
  int64_t  linenumber;        /* What line of the file  (1..N; -1=unknown)*/
  off_t    bookmark_offset;   /* bookmark fwd position before reversing...*/
  int64_t  bookmark_linenum;  /* in both linenumber and disk offset       */

  /* In digital mode, we have an alphabet ptr                             */
  int   do_digital;       /* TRUE if we're reading in digital mode    */
#if defined(eslAUGMENT_ALPHABET)  
  const ESL_ALPHABET *abc;
#else
  void               *abc;
#endif

  /* Format-specific configuration                                           */
  int   format;           /* Format code of this file                    */
  int   is_linebased;         /* TRUE for fgets() parsers; FALSE for fread() */
  int   eof_is_ok;        /* TRUE if record can end on EOF               */
  int  (*parse_header)(struct esl_sqfile_s *, ESL_SQ *sq);
  int  (*parse_end)   (struct esl_sqfile_s *, ESL_SQ *sq); 
  ESL_DSQ inmap[128];         /* an input map, 0..127                        */

  /* MSA augmentation confers reading MSA files as sequential seq files. */
#if defined(eslAUGMENT_MSA)
  ESL_MSAFILE *afp;       /* open ESL_MSAFILE for reading           */
  ESL_MSA     *msa;       /* preloaded alignment to draw seqs from  */
  int          idx;       /* index of next seq to return, 0..nseq-1 */
#else
  void        *afp;           /* NULL */
  void        *msa;           /* NULL */
  int          idx;           /* 0    */
#endif /*eslAUGMENT_MSA*/

  /* SSI augmentation confers random access of records in a seq file        */
  char    *ssifile;       /* path to expected SSI index file            */
  int      rpl;           /* residues per line in file; -1=unset 0=inval*/
  int      bpl;           /* bytes per line in file; -1=unset, 0=inval  */
  int      currpl;        /* residues on current line (-1=unknown)      */
  int      curbpl;        /* bytes on current line    (-1=unknown)      */
  int      prvrpl;        /* residues on previous line                  */
  int      prvbpl;        /* bytes on previous line                     */
#if defined(eslAUGMENT_SSI)
  ESL_SSI *ssi;     /* open ESL_SSI index, or NULL if none     */
#else
  void    *ssi;     /* NULL */
#endif /*eslAUGMENT_SSI*/
} ESL_SQFILE;

I want to store the struct value into file and read it when needed. The problem that if I write the whole struct some values will contain an address rather than value. is there any solution for this problem

Upvotes: 2

Views: 1075

Answers (4)

Mihai8
Mihai8

Reputation: 3147

If you could push your imagination to find a serialization mechanism. It would be interesting to imagine how you could store it in a structured file of XML type, and how you can use a dictionary to hold correspondence with primitive data types.

Upvotes: 1

unwind
unwind

Reputation: 399753

As you've discovered, you can't usefully store pointers to disk. The pointer values will be meaningless when you attempt to load the data in, you need to properly serialize the data.

It's pretty typical that the external representation, the one that is optimized for storage and/or communication, is different from the optimal internal representation, which is optimized for actually being used by the program.

It's also a bad idea in C to expect to save/load entire structs as units, since there can be compiler-added "invisible" padding bytes between the fields. This can lead to the structure failing to load in a future version of your program, if you've switched compilers, compiler flags, or computers in the meantime.

It's best to write a function to save the structure, and one to load it, and let them go through the structure field by field and do whatever transform is necessary to take each field to/from its preferred external representation.

If you need to do this a lot, there are "middleware" solutions that let you define your structs in a domain-specific language, and then generate the code to do the save/load and runtime management.

Upvotes: 2

Ivaylo Strandjev
Ivaylo Strandjev

Reputation: 70931

You will have also to store the data the pointers are pointing to. There can be no other solution for what you need.

Upvotes: 2

cnicutar
cnicutar

Reputation: 182619

The problem that if I write the whole struct some values will contain an address rather than value. is there any solution for this problem

The only true solution is to manually write every member of the structure to the file. I.e. define your own pack function that does the right thing for every member.

Upvotes: 3

Related Questions