我有一个结构
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;
我想将struct值存储到文件中并在需要时读取它。问题是,如果我编写整个结构的某些值将包含地址而不是值。有没有解决这个问题的方法
答案 0 :(得分:3)
如果我编写整个结构的某些值将包含的问题 地址而不是价值。有没有解决这个问题的方法
唯一真正的解决方案是手动将结构的每个成员写入文件。即定义你自己的pack
函数,为每个成员做正确的事。
答案 1 :(得分:2)
您还必须存储指针指向的数据。没有其他解决方案可以满足您的需求。
答案 2 :(得分:2)
正如您所发现的,您无法有效地存储指向磁盘的指针。当您尝试加载数据时,指针值将毫无意义,您需要正确序列化数据。
外部表示(针对存储和/或通信进行了优化的外部表示)与最佳内部表示不同,这是最典型的,内部表示针对程序实际使用进行了优化。
在C中,期望将整个结构体保存/加载为单位也是一个坏主意,因为在字段之间可能存在编译器添加的“不可见”填充字节。如果您在此期间切换了编译器,编译器标志或计算机,这可能导致结构无法在程序的未来版本中加载。
最好编写一个函数来保存结构,然后编写一个函数来加载它,然后让它们逐个字段地遍历结构,并进行必要的转换以使每个字段与其首选的外部表示形式相同。
如果你需要做很多事情,有一些“中间件”解决方案可以让你用特定于域的语言定义你的结构,然后生成代码来进行保存/加载和运行时管理。
答案 3 :(得分:1)
如果你能发挥你的想象力去寻找序列化机制。有趣的是,想象一下如何将它存储在XML类型的结构化文件中,以及如何使用字典来保存与原始数据类型的对应关系。