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

发布于 2024-11-03 05:28:19 字数 1053 浏览 1 评论 0原文

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

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;
}

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

除了查找错误之外,还有改进代码的建议吗?

I am implementing a buffer of fixed length to read or write a string using a tail or head pointer respectively. I have the following code:

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;
}

This code works until maximum buffer is hit, when head pointer starts again, tail pointer is not placed properly.

Any suggestions in improving the code, apart from finding the bugs?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

最丧也最甜 2024-11-10 05:28:19

对于循环缓冲区,至少有两种方法可以区分满状态和空状态(在这两种情况下都是head == tail)。

  1. 允许缓冲区中多一项,而不是实际需要的项,并且在添加时不要让 head 前进到 tail (而是引发“缓冲区已满”错误)。这样,head == tail总是意味着空。

  2. 维护一个“空闲槽”变量以及头部和尾部,将其初始化为缓冲区的大小,在添加时递减,在删除时递增。这样,您可以通过将缓冲区设置为零来检测缓冲区已满,或者如果将缓冲区设置为原始大小,则可以检测缓冲区为空。


对于选项 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

With a circular buffer, there are at least two ways to distinguish a full state from an empty one (head == tail in both those cases).

  1. Allow for one more item in the buffer than you actually need and don't ever let head advance to tail when adding (raise a "buffer full" error instead). That way, head == tail always means empty.

  2. Maintain a "free slots" variable as well as the head and tail, initialising it to the size of the buffer, decrementing it when adding and incrementing when removing. That way you can detect buffer full by the fact that it's set to zero, or buffer empty if it's set to the original size.


For option 1, something like:

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

For option 2, something like:

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文