Reputation: 51
I want to make a circular array of a fixed size, and I want to add elements to it and then should be able to print it, when the array is full the new added elements should take place of the old elements
example
...
list_add('a'); //add element 'a'
list_add('b'); //add element 'b'
list_add('c'); //add element 'c'
list_print(); // should print 'a', 'b', 'c'
list_add('d'); //add element 'd'
list_add('e'); //add element 'e'
list_print(); // should print 'c', 'd', 'e'
...
at first I though , it would be easy with some hack but it gave me a headache :( here is what I did
#include <stdio.h>
#include <stdlib.h>
void list_add(char element);
void list_print();
char list[3] = {0, 0, 0};
int idx = 0;
int main(){
list_add('a');
list_add('b');
list_add('c');
list_print();
list_add('d');
list_add('e');
list_print();
return 0;
}
void list_add(char element){
list[idx] = element;
idx++;
if(idx==3) idx=0;
}
void list_print(){
int i;
for (i=0;i<3;i++) printf("%c\n", list[i]);
}
Upvotes: 2
Views: 6839
Reputation: 40145
#define SIZE 3
char list[SIZE] = {0};
//...
void list_print(void){
int n = SIZE;
int i = idx;
while(n--){
printf("%c ", list[i++ % SIZE]);
}
printf("\n");
}
Upvotes: 0
Reputation: 8589
If you want it to print out from the oldest element look at your list_add
code and your list_print
.
list_add
'knows' where the insertion point is but list_print
always starts from 0.
You probably want to start from idx
as the 'oldest' element.
I would check to see if it is 0
as they are 'empty' slots before the circle is complete.
Try:
void list_print(){
int i=idx;//Start at the insertion point - just after the last insert - if any.
do{
if(list[i]!=0){//Don't output unfilled entries. Just a suggestion.
//You can't now store 0 but that's probably OK for most purposes.
printf("%c\n", list[i]);
}
++i;//Increment i and watch for looping like you did in list_add().
if(i==3){
i=0;
}
}while(i!=idx);//Stop when we're back at the beginning.
}
Upvotes: 2
Reputation: 106
Is there a chance that you just haven't noticed that your code is fine? It works the way it should. You add a, b, c. Then you add d and e which replace the array circularly: d, e, c. Illustration:
{0,0,0}
{a,0,0}
{a,b,0}
{a,b,c}
{d,b,c}
{d,e,c}
Or am I missing something here?
Is that the way you wanted?
int indicator = 0;
<...>
void list_add(char element) {
if((idx < 3) && !indicator) {
list[idx] = element; idx++;
} else {
indicator = 1;
list[idx - 1] = element; idx--;
if (idx == 0) {
idx = 3;
}
};
And what about now? :)
void list_add(char element){
if((idx < 3) && !indicator) {
list[idx] = element; idx++;
} else {
indicator = 1;
list[idx - 3] = list[idx - 2];
list[idx - 2] = list[idx -1];
list[idx - 1] = element;
};
}
It fills the array normally until 3. Then it loops by shifting all the elements and then inserts a new value. You will have to add some dynamics to it (loop) if you want to create, lets say, a dynamic array.
Upvotes: 0