⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 00000016.htm

📁 一份很好的linux入门资料
💻 HTM
📖 第 1 页 / 共 5 页
字号:
&nbsp;for&nbsp;(ptr&nbsp;=&nbsp;key,&nbsp;i&nbsp;=&nbsp;1;&nbsp;c&nbsp;=&nbsp;*ptr++;&nbsp;i++)&nbsp;&nbsp;<BR>&nbsp;&nbsp;hval&nbsp;+=&nbsp;c&nbsp;*&nbsp;i;&nbsp;&nbsp;/*&nbsp;ascii&nbsp;char&nbsp;times&nbsp;its&nbsp;1-based&nbsp;index&nbsp;*/&nbsp;&nbsp;<BR>&nbsp;return(hval&nbsp;%&nbsp;db-&gt;nhash);&nbsp;&nbsp;<BR>}&nbsp;&nbsp;<BR>程序16.9&nbsp;_db_hash函数&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;_db_find调用的下一个函数是_db_readptr(程序16.10)。这个函数能够读取&nbsp;&nbsp;<BR>以下三种不同的链指针中的任意一种:(1)索引文件最开始的空闲链表指针。(&nbsp;&nbsp;<BR>2)Hash表中指向Hash链的第一条索引记录的指针。(3)每条索引记录头的指向下&nbsp;&nbsp;<BR>一条记录的指针(这里的索引记录既可以处于一条Hash链表中,也可以处于空闲链&nbsp;&nbsp;<BR>表中)。这个函数的调用者应做好必要的加锁,此函数不进行任何加锁。&nbsp;&nbsp;<BR>#include&nbsp;&quot;db.h&quot;&nbsp;&nbsp;<BR>/*&nbsp;Read&nbsp;a&nbsp;chain&nbsp;ptr&nbsp;field&nbsp;from&nbsp;anywhere&nbsp;in&nbsp;the&nbsp;index&nbsp;file:&nbsp;&nbsp;<BR>&nbsp;*&nbsp;the&nbsp;free&nbsp;list&nbsp;pointer,&nbsp;a&nbsp;hash&nbsp;table&nbsp;chain&nbsp;ptr,&nbsp;or&nbsp;an&nbsp;&nbsp;<BR>&nbsp;*&nbsp;index&nbsp;record&nbsp;chain&nbsp;ptr.&nbsp;&nbsp;*/&nbsp;&nbsp;<BR>off_t&nbsp;&nbsp;<BR>_db_readptr(DB&nbsp;*db,&nbsp;off_t&nbsp;offset)&nbsp;&nbsp;<BR>{&nbsp;&nbsp;<BR>&nbsp;char&nbsp;asciiptr[PTR_SZ&nbsp;+&nbsp;1];&nbsp;&nbsp;<BR>&nbsp;if&nbsp;(lseek(db-&gt;idxfd,&nbsp;offset,&nbsp;SEEK_SET)&nbsp;==&nbsp;-1)&nbsp;&nbsp;<BR>&nbsp;&nbsp;err_dump(&quot;lseek&nbsp;error&nbsp;to&nbsp;ptr&nbsp;field&quot;);&nbsp;&nbsp;<BR>&nbsp;if&nbsp;(read(db-&gt;idxfd,&nbsp;asciiptr,&nbsp;PTR_SZ)&nbsp;!=&nbsp;PTR_SZ)&nbsp;&nbsp;<BR>&nbsp;&nbsp;err_dump(&quot;read&nbsp;error&nbsp;of&nbsp;ptr&nbsp;field&quot;);&nbsp;&nbsp;<BR>&nbsp;asciiptr[PTR_SZ]&nbsp;=&nbsp;0;&nbsp;&nbsp;/*&nbsp;null&nbsp;terminate&nbsp;*/&nbsp;&nbsp;<BR>&nbsp;return(atol(asciiptr));&nbsp;&nbsp;<BR>}&nbsp;&nbsp;<BR>程序16.10&nbsp;_db_readptr函数&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;_db_find中的while循环通过调用_db_readidx来读取各条索引记录。_db_rea&nbsp;&nbsp;<BR>didx(程序16.11)是一个较长的函数,这个函数读取索引记录,并将索引记录的&nbsp;&nbsp;<BR>信息存储到适当的字段中。&nbsp;&nbsp;<BR>#include&nbsp;&quot;db.h&quot;&nbsp;&nbsp;<BR>#include&nbsp;&lt;sys/uio.h&gt;&nbsp;&nbsp;/*&nbsp;struct&nbsp;iovec&nbsp;*/&nbsp;&nbsp;<BR>/*&nbsp;Read&nbsp;the&nbsp;next&nbsp;index&nbsp;record.&nbsp;&nbsp;We&nbsp;start&nbsp;at&nbsp;the&nbsp;specified&nbsp;offset&nbsp;in&nbsp;&nbsp;<BR>&nbsp;*&nbsp;the&nbsp;index&nbsp;file.&nbsp;&nbsp;We&nbsp;read&nbsp;the&nbsp;index&nbsp;record&nbsp;into&nbsp;db-&gt;idxbuf&nbsp;and&nbsp;&nbsp;<BR>&nbsp;*&nbsp;replace&nbsp;the&nbsp;separators&nbsp;with&nbsp;null&nbsp;bytes.&nbsp;&nbsp;If&nbsp;all&nbsp;is&nbsp;OK&nbsp;we&nbsp;set&nbsp;&nbsp;<BR>&nbsp;*&nbsp;db-&gt;datoff&nbsp;and&nbsp;db-&gt;datlen&nbsp;to&nbsp;the&nbsp;offset&nbsp;and&nbsp;length&nbsp;of&nbsp;the&nbsp;&nbsp;<BR>&nbsp;*&nbsp;corresponding&nbsp;data&nbsp;record&nbsp;in&nbsp;the&nbsp;data&nbsp;file.&nbsp;&nbsp;*/&nbsp;&nbsp;<BR>off_t&nbsp;&nbsp;<BR>_db_readidx(DB&nbsp;*db,&nbsp;off_t&nbsp;offset)&nbsp;&nbsp;<BR>{&nbsp;&nbsp;<BR>&nbsp;int&nbsp;&nbsp;&nbsp;&nbsp;i;&nbsp;&nbsp;<BR>&nbsp;char&nbsp;&nbsp;&nbsp;*ptr1,&nbsp;*ptr2;&nbsp;&nbsp;<BR>&nbsp;char&nbsp;&nbsp;&nbsp;asciiptr[PTR_SZ&nbsp;+&nbsp;1],&nbsp;asciilen[IDXLEN_SZ&nbsp;+&nbsp;1];&nbsp;&nbsp;<BR>&nbsp;struct&nbsp;iovec&nbsp;iov[2];&nbsp;&nbsp;<BR>&nbsp;&nbsp;/*&nbsp;Position&nbsp;index&nbsp;file&nbsp;and&nbsp;record&nbsp;the&nbsp;offset.&nbsp;&nbsp;db_nextrec()&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;calls&nbsp;us&nbsp;with&nbsp;offset==0,&nbsp;meaning&nbsp;read&nbsp;from&nbsp;current&nbsp;offset.&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;We&nbsp;still&nbsp;need&nbsp;to&nbsp;call&nbsp;lseek()&nbsp;to&nbsp;record&nbsp;the&nbsp;current&nbsp;offset.&nbsp;*/&nbsp;&nbsp;<BR>&nbsp;if&nbsp;(&nbsp;(db-&gt;idxoff&nbsp;=&nbsp;lseek(db-&gt;idxfd,&nbsp;offset,&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;offset&nbsp;==&nbsp;0&nbsp;?&nbsp;SEEK_CUR&nbsp;:&nbsp;SEEK_SET))&nbsp;==&nbsp;-1)&nbsp;&nbsp;<BR>&nbsp;&nbsp;err_dump(&quot;lseek&nbsp;error&quot;);&nbsp;&nbsp;<BR>&nbsp;&nbsp;/*&nbsp;Read&nbsp;the&nbsp;ascii&nbsp;chain&nbsp;ptr&nbsp;and&nbsp;the&nbsp;ascii&nbsp;length&nbsp;at&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;the&nbsp;front&nbsp;of&nbsp;the&nbsp;index&nbsp;record.&nbsp;&nbsp;This&nbsp;tells&nbsp;us&nbsp;the&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;remaining&nbsp;size&nbsp;of&nbsp;the&nbsp;index&nbsp;record.&nbsp;*/&nbsp;&nbsp;<BR>&nbsp;iov[0].iov_base&nbsp;=&nbsp;asciiptr;&nbsp;&nbsp;<BR>&nbsp;iov[0].iov_len&nbsp;&nbsp;=&nbsp;PTR_SZ;&nbsp;&nbsp;<BR>&nbsp;iov[1].iov_base&nbsp;=&nbsp;asciilen;&nbsp;&nbsp;<BR>&nbsp;iov[1].iov_len&nbsp;&nbsp;=&nbsp;IDXLEN_SZ;&nbsp;&nbsp;<BR>&nbsp;if&nbsp;(&nbsp;(i&nbsp;=&nbsp;readv(db-&gt;idxfd,&nbsp;&amp;iov[0],&nbsp;2))&nbsp;!=&nbsp;PTR_SZ&nbsp;+&nbsp;IDXLEN_SZ)&nbsp;{&nbsp;&nbsp;<BR>&nbsp;&nbsp;if&nbsp;(i&nbsp;==&nbsp;0&nbsp;&amp;&amp;&nbsp;offset&nbsp;==&nbsp;0)&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;return(-1);&nbsp;&nbsp;/*&nbsp;EOF&nbsp;for&nbsp;db_nextrec()&nbsp;*/&nbsp;&nbsp;<BR>&nbsp;&nbsp;err_dump(&quot;readv&nbsp;error&nbsp;of&nbsp;index&nbsp;record&quot;);&nbsp;&nbsp;<BR>&nbsp;}&nbsp;&nbsp;<BR>&nbsp;asciiptr[PTR_SZ]&nbsp;=&nbsp;0;&nbsp;&nbsp;&nbsp;/*&nbsp;null&nbsp;terminate&nbsp;*/&nbsp;&nbsp;<BR>&nbsp;db-&gt;ptrval&nbsp;=&nbsp;atol(asciiptr);&nbsp;/*&nbsp;offset&nbsp;of&nbsp;next&nbsp;key&nbsp;in&nbsp;chain&nbsp;*/&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;this&nbsp;is&nbsp;our&nbsp;return&nbsp;value;&nbsp;always&nbsp;&gt;=&nbsp;0&nbsp;*/&nbsp;&nbsp;<BR>&nbsp;asciilen[IDXLEN_SZ]&nbsp;=&nbsp;0;&nbsp;&nbsp;/*&nbsp;null&nbsp;terminate&nbsp;*/&nbsp;&nbsp;<BR>&nbsp;if&nbsp;(&nbsp;(db-&gt;idxlen&nbsp;=&nbsp;atoi(asciilen))&nbsp;&lt;&nbsp;IDXLEN_MIN&nbsp;||&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;db-&gt;idxlen&nbsp;&gt;&nbsp;IDXLEN_MAX)&nbsp;&nbsp;<BR>&nbsp;&nbsp;err_dump(&quot;invalid&nbsp;length&quot;);&nbsp;&nbsp;<BR>&nbsp;&nbsp;/*&nbsp;Now&nbsp;read&nbsp;the&nbsp;actual&nbsp;index&nbsp;record.&nbsp;&nbsp;We&nbsp;read&nbsp;it&nbsp;into&nbsp;the&nbsp;key&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;buffer&nbsp;that&nbsp;we&nbsp;malloced&nbsp;when&nbsp;we&nbsp;opened&nbsp;the&nbsp;database.&nbsp;*/&nbsp;&nbsp;<BR>&nbsp;if&nbsp;(&nbsp;(i&nbsp;=&nbsp;read(db-&gt;idxfd,&nbsp;db-&gt;idxbuf,&nbsp;db-&gt;idxlen))&nbsp;!=&nbsp;db-&gt;idxlen)&nbsp;&nbsp;<BR>&nbsp;&nbsp;err_dump(&quot;read&nbsp;error&nbsp;of&nbsp;indexc&nbsp;record&quot;);&nbsp;&nbsp;<BR>&nbsp;if&nbsp;(db-&gt;idxbuf[db-&gt;idxlen-1]&nbsp;!=&nbsp;'\n')&nbsp;&nbsp;<BR>&nbsp;&nbsp;err_dump(&quot;missing&nbsp;newline&quot;);&nbsp;/*&nbsp;sanity&nbsp;checks&nbsp;*/&nbsp;&nbsp;<BR>&nbsp;db-&gt;idxbuf[db-&gt;idxlen-1]&nbsp;=&nbsp;0;&nbsp;&nbsp;/*&nbsp;replace&nbsp;newline&nbsp;with&nbsp;null&nbsp;*/&nbsp;&nbsp;<BR>&nbsp;&nbsp;/*&nbsp;Find&nbsp;the&nbsp;separators&nbsp;in&nbsp;the&nbsp;index&nbsp;record&nbsp;*/&nbsp;&nbsp;<BR>&nbsp;if&nbsp;(&nbsp;(ptr1&nbsp;=&nbsp;strchr(db-&gt;idxbuf,&nbsp;SEP))&nbsp;==&nbsp;NULL)&nbsp;&nbsp;<BR>&nbsp;&nbsp;err_dump(&quot;missing&nbsp;first&nbsp;separator&quot;);&nbsp;&nbsp;<BR>&nbsp;*ptr1++&nbsp;=&nbsp;0;&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;replace&nbsp;SEP&nbsp;with&nbsp;null&nbsp;*/&nbsp;&nbsp;<BR>&nbsp;if&nbsp;(&nbsp;(ptr2&nbsp;=&nbsp;strchr(ptr1,&nbsp;SEP))&nbsp;==&nbsp;NULL)&nbsp;&nbsp;<BR>&nbsp;&nbsp;err_dump(&quot;missing&nbsp;second&nbsp;separator&quot;);&nbsp;&nbsp;<BR>&nbsp;*ptr2++&nbsp;=&nbsp;0;&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;replace&nbsp;SEP&nbsp;with&nbsp;null&nbsp;*/&nbsp;&nbsp;<BR>&nbsp;if&nbsp;(strchr(ptr2,&nbsp;SEP)&nbsp;!=&nbsp;NULL)&nbsp;&nbsp;<BR>&nbsp;asciiptr[PTR_SZ]&nbsp;=&nbsp;0;&nbsp;&nbsp;&nbsp;/*&nbsp;null&nbsp;terminate&nbsp;*/&nbsp;&nbsp;<BR>&nbsp;db-&gt;ptrval&nbsp;=&nbsp;atol(asciiptr);&nbsp;/*&nbsp;offset&nbsp;of&nbsp;next&nbsp;key&nbsp;in&nbsp;chain&nbsp;*/&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;this&nbsp;is&nbsp;our&nbsp;return&nbsp;value;&nbsp;always&nbsp;&gt;=&nbsp;0&nbsp;*/&nbsp;&nbsp;<BR>&nbsp;asciilen[IDXLEN_SZ]&nbsp;=&nbsp;0;&nbsp;&nbsp;/*&nbsp;null&nbsp;terminate&nbsp;*/&nbsp;&nbsp;<BR>&nbsp;if&nbsp;(&nbsp;(db-&gt;idxlen&nbsp;=&nbsp;atoi(asciilen))&nbsp;&lt;&nbsp;IDXLEN_MIN&nbsp;||&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;db-&gt;idxlen&nbsp;&gt;&nbsp;IDXLEN_MAX)&nbsp;&nbsp;<BR>&nbsp;&nbsp;err_dump(&quot;invalid&nbsp;length&quot;);&nbsp;&nbsp;<BR>&nbsp;&nbsp;/*&nbsp;Now&nbsp;read&nbsp;the&nbsp;actual&nbsp;index&nbsp;record.&nbsp;&nbsp;We&nbsp;read&nbsp;it&nbsp;into&nbsp;the&nbsp;key&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;buffer&nbsp;that&nbsp;we&nbsp;malloced&nbsp;when&nbsp;we&nbsp;opened&nbsp;the&nbsp;database.&nbsp;*/&nbsp;&nbsp;<BR>&nbsp;if&nbsp;(&nbsp;(i&nbsp;=&nbsp;read(db-&gt;idxfd,&nbsp;db-&gt;idxbuf,&nbsp;db-&gt;idxlen))&nbsp;!=&nbsp;db-&gt;idxlen)&nbsp;&nbsp;<BR>&nbsp;&nbsp;err_dump(&quot;read&nbsp;error&nbsp;of&nbsp;indexc&nbsp;record&quot;);&nbsp;&nbsp;<BR>&nbsp;if&nbsp;(db-&gt;idxbuf[db-&gt;idxlen-1]&nbsp;!=&nbsp;'\n')&nbsp;&nbsp;<BR>&nbsp;&nbsp;err_dump(&quot;missing&nbsp;newline&quot;);&nbsp;/*&nbsp;sanity&nbsp;checks&nbsp;*/&nbsp;&nbsp;<BR>&nbsp;db-&gt;idxbuf[db-&gt;idxlen-1]&nbsp;=&nbsp;0;&nbsp;&nbsp;/*&nbsp;replace&nbsp;newline&nbsp;with&nbsp;null&nbsp;*/&nbsp;&nbsp;<BR>&nbsp;&nbsp;/*&nbsp;Find&nbsp;the&nbsp;separators&nbsp;in&nbsp;the&nbsp;index&nbsp;record&nbsp;*/&nbsp;&nbsp;<BR>&nbsp;if&nbsp;(&nbsp;(ptr1&nbsp;=&nbsp;strchr(db-&gt;idxbuf,&nbsp;SEP))&nbsp;==&nbsp;NULL)&nbsp;&nbsp;<BR>&nbsp;&nbsp;err_dump(&quot;missing&nbsp;first&nbsp;separator&quot;);&nbsp;&nbsp;<BR>&nbsp;*ptr1++&nbsp;=&nbsp;0;&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;replace&nbsp;SEP&nbsp;with&nbsp;null&nbsp;*/&nbsp;&nbsp;<BR>&nbsp;if&nbsp;(&nbsp;(ptr2&nbsp;=&nbsp;strchr(ptr1,&nbsp;SEP))&nbsp;==&nbsp;NULL)&nbsp;&nbsp;<BR>&nbsp;&nbsp;err_dump(&quot;missing&nbsp;second&nbsp;separator&quot;);&nbsp;&nbsp;<BR>&nbsp;*ptr2++&nbsp;=&nbsp;0;&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;replace&nbsp;SEP&nbsp;with&nbsp;null&nbsp;*/&nbsp;&nbsp;<BR>&nbsp;if&nbsp;(strchr(ptr2,&nbsp;SEP)&nbsp;!=&nbsp;NULL)&nbsp;&nbsp;<BR>&nbsp;&nbsp;err_dump(&quot;too&nbsp;many&nbsp;separators&quot;);&nbsp;&nbsp;<BR>&nbsp;&nbsp;/*&nbsp;Get&nbsp;the&nbsp;starting&nbsp;offset&nbsp;and&nbsp;length&nbsp;of&nbsp;the&nbsp;data&nbsp;record&nbsp;*/&nbsp;&nbsp;<BR>&nbsp;if&nbsp;(&nbsp;(db-&gt;datoff&nbsp;=&nbsp;atol(ptr1))&nbsp;&lt;&nbsp;0)&nbsp;&nbsp;<BR>&nbsp;&nbsp;err_dump(&quot;starting&nbsp;offset&nbsp;&lt;&nbsp;0&quot;);&nbsp;&nbsp;<BR>&nbsp;if&nbsp;(&nbsp;(db-&gt;datlen&nbsp;=&nbsp;atol(ptr2))&nbsp;&lt;=&nbsp;0&nbsp;||&nbsp;db-&gt;datlen&nbsp;&gt;&nbsp;DATLEN_MAX)&nbsp;&nbsp;<BR>&nbsp;&nbsp;err_dump(&quot;invalid&nbsp;length&quot;);&nbsp;&nbsp;<BR>&nbsp;return(db-&gt;ptrval);&nbsp;&nbsp;/*&nbsp;return&nbsp;offset&nbsp;of&nbsp;next&nbsp;key&nbsp;in&nbsp;chain&nbsp;*/&nbsp;&nbsp;<BR>}&nbsp;&nbsp;<BR>程序16.11&nbsp;_db_readidx函数&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;我们调用readv来读取索引记录开始处的两个固定长度的字段:指向下一条索&nbsp;&nbsp;<BR>引记录的链指针和索引记录剩下的不定长部分的长度。然后,索引记录的剩下的部&nbsp;&nbsp;<BR>分被读入:主键、数据记录的偏移量和数据记录的长度。我们并不读数据记录,这&nbsp;&nbsp;<BR>由调用者自己完成。例如,在db_fetch中,在_db_find按主键找到索引记录前是不&nbsp;&nbsp;<BR>去读取数据记录的。&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;下面我们回到db_fetch。如果_db_find找到了索引记录,我们调用_db_readd&nbsp;&nbsp;<BR>at来读取对应的数据记录。这是一个很简单的函数(见程序16.12)。&nbsp;&nbsp;<BR>#include&nbsp;&quot;db.h&quot;&nbsp;&nbsp;<BR>/*&nbsp;Read&nbsp;the&nbsp;current&nbsp;data&nbsp;record&nbsp;into&nbsp;the&nbsp;data&nbsp;buffer.&nbsp;&nbsp;<BR>&nbsp;*&nbsp;Return&nbsp;a&nbsp;pointer&nbsp;to&nbsp;the&nbsp;null-terminated&nbsp;data&nbsp;buffer.&nbsp;*/&nbsp;&nbsp;<BR>char&nbsp;*&nbsp;&nbsp;<BR>_db_readdat(DB&nbsp;*db)&nbsp;&nbsp;<BR>{&nbsp;&nbsp;<BR>&nbsp;if&nbsp;(lseek(db-&gt;datfd,&nbsp;db-&gt;datoff,&nbsp;SEEK_SET)&nbsp;==&nbsp;-1)&nbsp;&nbsp;<BR>&nbsp;&nbsp;err_dump(&quot;lseek&nbsp;error&quot;);&nbsp;&nbsp;<BR>&nbsp;if&nbsp;(read(db-&gt;datfd,&nbsp;db-&gt;datbuf,&nbsp;db-&gt;datlen)&nbsp;!=&nbsp;db-&gt;datlen)&nbsp;&nbsp;<BR>&nbsp;&nbsp;err_dump(&quot;read&nbsp;error&quot;);&nbsp;&nbsp;<BR>&nbsp;if&nbsp;(db-&gt;datbuf[db-&gt;datlen&nbsp;-&nbsp;1]&nbsp;!=&nbsp;'\n')&nbsp;&nbsp;/*&nbsp;sanity&nbsp;check&nbsp;*/&nbsp;&nbsp;<BR>&nbsp;&nbsp;err_dump(&quot;missing&nbsp;newline&quot;);&nbsp;&nbsp;<BR>&nbsp;db-&gt;datbuf[db-&gt;datlen&nbsp;-&nbsp;1]&nbsp;=&nbsp;0;&nbsp;&nbsp;/*&nbsp;replace&nbsp;newline&nbsp;with&nbsp;null&nbsp;*/&nbsp;&nbsp;<BR>&nbsp;return(db-&gt;datbuf);&nbsp;&nbsp;/*&nbsp;return&nbsp;pointer&nbsp;to&nbsp;data&nbsp;record&nbsp;*/&nbsp;&nbsp;<BR>}&nbsp;&nbsp;<BR>程序16.12&nbsp;_de_readdat函数&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;我们从db_fetch开始,现在已经读取了索引记录和对应的数据记录。注意到,&nbsp;&nbsp;<BR>我们只在_db_find中加了一个读

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -