How To Implement A Simple Circular Buffer In C

We’ll come back to those later.

Here’s a visual representation of that same array as a circular buffer:All I did was connect the end back to the beginning.

What Are We Implementing?We’ll be creating a program to demonstrate an 8 location circular buffer of integers.

We’ll be implementing a FIFO (First In First Out) buffer.

We’ll be able to input (write) and output (read) values from the buffer.

If the buffer is full, we won’t be able to write any more values.

If the buffer is empty, we won’t be able to read any more values.

What Variables Do We Need?NOTE: Always remember to initialize your variables to 0First, we need to store the size of the circular buffer that we’re implementing.

A good way to store this information is in a constant.

#define SIZE_OF_BUFFER 8Next, we’ll need a variable to store the buffer length.

The buffer length is the current number of filled elements (elements we’ve written to).

Each time we write a new value, we’ll increment the buffer length by 1.

Each time we read a value, we’ll decrement the buffer length by 1.

int bufferLength = 0;We also need an integer to store the index position to write to and an integer to store the index position to read from.

int readIndex = 0;int writeIndex = 0;How Can We Get User Input?There are a lot of methods to get an integer value through user input in C.

I’ll be using a little function called getNumber() in this guide.

It takes in a pointer to an int as a parameter, gets user input using fgets(), parses the integer from that input using sscanf() and stores it in the address the parameter is pointing to.

Let’s Input Some Values!The first thing we need to do is check if the buffer is full.

If it is, we can’t write to it!.Remember that bufferLength variable we’re using to keep track of how many elements we have?.All we need to do is make sure that doesn’t equal the number of locations we have.

We can compare our bufferLength variable and our SIZE_OF_BUFFER constant.

If they’re equal, we’ll print an error message.

if (bufferLength == SIZE_OF_BUFFER){ printf(“Buffer is full!”);}We won’t be writing the full code in this guide, but if you are, always remember to prompt the user for the input!.Remember, our getNumber() function takes in a pointer to an int.

To input (write) a value, we need to pass in the address in memory of the index we want to write to into the getNumber() function.

getNumber(&circularBuffer[writeIndex]);That will write a value to the 0th position in the circular buffer.

Let’s say we input the number 5.

Here’s a visual representation:Now that we’ve written our first value, we need to update our bufferLength variable to keep track of how many values we have.

bufferLength++;Now we need to move our write position to the next location in the circular buffer.

We just need to increment our writeIndex variable by 1.

writeIndex++;We’re almost there!.Now we have to figure out what to do if we’ve written to the last location and our write position needs to be incremented.

Here’s a visual representation:Remember, we’re implementing a circular buffer.

The last location attaches to the first location.

If our writeIndex variable is equal to the number of locations we have (circularBuffer[7]), we simply need to set it back to location 0 (circularBuffer[0]).

if (writeIndex == SIZE_OF_BUFFER){ writeIndex = 0;}Now our write index is right back to the start!.Our check to make sure that our bufferLength variable is less than our SIZE_OF_BUFFER is preventing us from writing over any data.

Put it all together and it looks something like this:if (bufferLength == SIZE_OF_BUFFER){ printf(“Buffer is full!”);}getNumber(&circularBuffer[writeIndex]);bufferLength++;writeIndex++;if (writeIndex == SIZE_OF_BUFFER) { writeIndex = 0;}Pretty simple, right?Let’s Output Some Values!We couldn’t write a value if the buffer was full and we can’t read a value if the buffer is empty!.Let’s use the same check we used before, but we’ll check if our bufferLength variable is equal to 0 this time.

if (bufferLength == 0) { printf(“Buffer is empty!”);}Now, let’s read our first value!.We’ll just be displaying this value on the screen as our way of “outputting” it.

Our readIndex variable is still at index 0 in the array, since we haven’t done anything with it.

Let’s print that 0th element.

printf(“The output value is %d”, circularBuffer[readIndex]);Now that we’ve read our first value, we need to update our bufferLength variable to keep track of how many values we have left.

bufferLength–;We also need to move our read position to the next location.

We just need to increment our readIndex variable by 1.

readIndex++;Here’s a visual representation (assuming we have input 5 values and just read our first value):Almost there!.All we have left to do is check if our read position is at the last position (circularBuffer[7]) and move it back to the first position (circularBuffer[0]) if it is, just like we did with the write position.

if (readIndex == SIZE_OF_BUFFER) { readIndex = 0;}Put it all together and it looks something like this:if (bufferLength == 0) { printf(“Buffer is empty!”);}bufferLength–;readIndex++;if (readIndex == SIZE_OF_BUFFER) { readIndex = 0;}How Does the Program Work?Of course, this isn’t the full program.

We’d need to include our libraries (#include <stdio.

h>) and it’d be nice to display a menu to the user that has a write option and a read option.

These options could be placed in a simple while loop (make sure to add a continue; if the buffer is full or empty so you don’t execute the code anyway).

We would need our getNumber() function as well, which might look something like this:#define SUCCESS 0#define FAILURE -1int getNumber(int* pNumber) { char userInput[MAX_LENGTH_OF_STRING] = { 0 }; fgets(userInput, MAX_LENGTH_OF_STRING, stdin); if (sscanf(userInput, “%d”, pNumber) != 1) { return FAILURE; } return SUCCESS;}That’s It!That’s all there is to it!If you want to take a look at a sample implementation, here’s a link to my GitHub repo:https://github.

com/charlesdobson/CircularBuffer.. More details

Leave a Reply