实现具有头尾指针的固定长度缓冲区

时间:2011-04-26 06:10:18

标签: c buffer

我正在实现一个固定长度的缓冲区,分别使用尾部或头部指针读取或写入字符串。我有以下代码:

bool putBuffer(char *sMsz)
{
 int iStrLen;
 iStrLen =  strlen(sMsz);
 if(!iStrLen || iStrLen>MAX_LEN)
 return 0;
  while(iStrLen-->=0)
 {
  //if head crosses tail
   if(iBufHead==iBufTail && iBufHead!=0 && dFlag)
   {  
     while(cDebugBuf[iBufTail] != '\0')
     {
       iBufTail=iBufTail+1;
       if (iBufTail>=CBUFF_SIZE)
       iBufTail = 0;
     }
    iBufTail++;
  }
     if(iBufHead>=CBUFF_SIZE)
    {
     dFlag=1; // Used to know when buffer starts over writing prev data and meets tail on                    way
    iBufHead = 0; 
    }
    cDebugBuf[iBufHead++] = *(sMsz++);
 }
 return 1;
}

 bool  getBuffer(char *readData)
 {
    int i=0; 
  do
  {
     if(iBufTail==iBufHead)
      return 0;
     if(iBufTail>=CBUFF_SIZE)
     iBufTail = 0;
     readData[i++] = cDebugBuf[iBufTail++];
   }while(cDebugBuf[iBufTail]!='\0');
   iBufTail++;
   return 1;
}

此代码一直有效,直到最大缓冲区被命中,当头指针再次启动时,尾指针未正确放置。

除了发现错误之外,还有任何改进代码的建议吗?

1 个答案:

答案 0 :(得分:1)

使用循环缓冲区,至少有两种方法可以区分完整状态和空状态(head == tail)。

  1. 允许缓冲区中的一个项目超出实际需要,并且在添加时不要让head前进到tail(而是提出“缓冲区已满”错误)。这样,head == tail 始终表示空。

  2. 保持“自由槽”变量以及头部和尾部,将其初始化为缓冲区的大小,在添加时递减,并在移除时递增。这样你可以通过设置为零来检测缓冲区已满,或者如果将缓冲区设置为原始大小则缓冲为空。


  3. 对于选项1,类似于:

    def buffInit(sz):
        global buffSz = sz
        global buffData = alloc(buffSz+1)         # allow for extra slot.
        global buffHead = 0
        global buffTail = 0
    
    def buffAdd(item):
        if (buffHead + 1) % buffSz == buffTail:   # never fill extra slot.
            return BUFFER_FULL
        buffData[buffHead] = item
        buffHead = (buffHead + 1) % buffSz
        return OK
    
    def buffGet():
        if buffHead == buffTail:
            return BUFFER_EMPTY
        item = buffData[buffHead]
        buffHead = (buffHead + 1) % buffSz
        return item
    

    对于选项2,类似于:

    def buffInit(sz):
        global buffSz = sz
        global buffFree = buffSz                  # extra information.
        global buffData = alloc(buffSz)
        global buffHead = 0
        global buffTail = 0
    
    def buffAdd(item):
        if buffFree == 0:                         # zero free slots means full.
            return BUFFER_FULL
        buffData[buffHead] = item
        buffHead = (buffHead + 1) % buffSz
        buffFree = buffFree - 1                   # keep in sync.
        return OK
    
    def buffGet():
        if buffFree == buffSz:
            return BUFFER_EMPTY
        item = buffData[buffHead]
        buffHead = (buffHead + 1) % buffSz
        buffFree = buffFree + 1                   # keep in sync.
        return item