2

我有一个结构

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;

我想将结构值存储到文件中并在需要时读取它。如果我编写整个结构,一些值将包含地址而不是值的问题。这个问题有什么解决办法吗

4

4 回答 4

3

如果我编写整个结构,一些值将包含地址而不是值的问题。这个问题有什么解决办法吗

唯一真正的解决方案是将结构的每个成员手动写入文件。即定义你自己的pack函数,为每个成员做正确的事情。

于 2012-12-28T17:44:05.353 回答
2

正如您所发现的,您无法有效地存储指向磁盘的指针。当您尝试加载数据时,指针值将毫无意义,您需要正确序列化数据。

很典型的是,针对存储和/或通信进行优化的外部表示与针对程序实际使用而优化的最佳内部表示不同。

在 C 中期望将整个结构作为单元保存/加载也是一个坏主意,因为在字段之间可能存在编译器添加的“不可见”填充字节。如果您同时切换了编译器、编译器标志或计算机,这可能会导致结构无法在程序的未来版本中加载。

最好编写一个函数来保存结构,并编写一个函数来加载它,然后让它们逐个字段地遍历结构,并进行必要的转换,以将每个字段与它的首选外部表示进行转换。

如果您需要做很多事情,有“中间件”解决方案可以让您以特定领域的语言定义结构,然后生成代码来执行保存/加载和运行时管理。

于 2012-12-28T17:48:25.440 回答
2

您还必须存储指针指向的数据。没有其他解决方案可以满足您的需求。

于 2012-12-28T17:44:44.447 回答
1

如果你能发挥你的想象力来找到一种序列化机制。想象一下如何将它存储在 XML 类型的结构化文件中,以及如何使用字典来保存与原始数据类型的对应关系,将会很有趣。

于 2012-12-28T17:52:20.117 回答