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

ポインターが指しているデータも保存する必要があります。必要なものに対する他の解決策はありません。

于 2012-12-28T17:44:44.447 に答える
2

あなたが発見したように、ポインターをディスクに保存することはできません。データをロードしようとすると、ポインター値は無意味になります。データを適切にシリアル化する必要があります。

ストレージおよび/または通信用に最適化された外部表現が、プログラムで実際に使用されるように最適化された最適な内部表現とは異なることは非常に一般的です。

構造体全体をユニットとして保存/ロードすることを C で期待するのも悪い考えです。これは、コンパイラによってフィールド間に「見えない」パディング バイトが追加される可能性があるためです。これにより、その間にコンパイラ、コンパイラ フラグ、またはコンピュータを切り替えた場合、プログラムの将来のバージョンで構造体の読み込みが失敗する可能性があります。

構造体を保存する関数とそれをロードする関数を作成し、フィールドごとに構造体を通過させ、各フィールドを優先する外部表現との間で取得するために必要な変換を行うのが最善です。

これを何度も行う必要がある場合は、ドメイン固有の言語で構造体を定義し、保存/読み込みとランタイム管理を行うコードを生成できる「ミドルウェア」ソリューションがあります。

于 2012-12-28T17:48:25.440 に答える
1

想像力を働かせてシリアル化のメカニズムを見つけることができれば。それを XML 型の構造化ファイルに格納する方法や、辞書を使用してプリミティブ データ型との対応を保持する方法を想像するのは興味深いことです。

于 2012-12-28T17:52:20.117 に答える