C 带sprintf的环形缓冲区
我正在尝试创建一个ringbuffer,并用拆分字符串元素数组填充它。缓冲区代码取自,运行良好 以下是我的主要任务和缓冲区实现:C 带sprintf的环形缓冲区,c,string,buffer,strtok,C,String,Buffer,Strtok,我正在尝试创建一个ringbuffer,并用拆分字符串元素数组填充它。缓冲区代码取自,运行良好 以下是我的主要任务和缓冲区实现: #include <stdio.h> #include <stdlib.h> #include <string.h> struct buffer { int size; int start; //int end; // position of last element /* Tracking s
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct buffer {
int size;
int start;
//int end; // position of last element
/* Tracking start and end of buffer would waste
* one position. A full buffer would always have
* to leave last position empty or otherwise
* it would look empty. Instead this buffer uses
* count to track if buffer is empty or full
*/
int count; // number of elements in buffer
/* Two ways to make buffer element type opaque
* First is by using typedef for the element
* pointer. Second is by using void pointer.
*/
/* different types of buffer:
int *element; // array of integers
char *element; // array of characters
void *element; // array of void type (could cast to int, char, etc)
char **element; //array of char pointers (array of strings)
void **element; // array of void pointers
Choosing array of void pointers since it's the most flexible */
char **element;
};
typedef struct buffer buffer_t;
void init(buffer_t *buffer, int size) {
buffer->size = size;
buffer->start = 0;
buffer->count = 0;
buffer->element = malloc(sizeof(buffer->element)*size);
/* allocated array of void pointers. Same as below */
//buffer->element = malloc(sizeof(void *) * size);
}
int full(buffer_t *buffer) {
if (buffer->count == buffer->size) {
return 1;
} else {
return 0;
}
}
int empty(buffer_t *buffer) {
if (buffer->count == 0) {
return 1;
} else {
return 0;
}
}
void push(buffer_t *buffer, void *data) {
int index;
if (full(buffer)) {
printf("Buffer overflow\n");
} else {
index = buffer->start + buffer->count++;
if (index >= buffer->size) {
index = 0;
}
buffer->element[index] = data;
}
}
void * popqueue(buffer_t *buffer) {
void * element;
if (empty(buffer)) {
printf("Buffer underflow\n");
return "0";
} else {
/* FIFO implementation */
element = buffer->element[buffer->start];
buffer->start++;
buffer->count--;
if (buffer->start == buffer->size) {
buffer->start = 0;
}
return element;
}
}
int main() {
char input[] = "[MVOLT][S1][M1]40.05[S1][M2]39.95";
char *string_buffer = malloc(sizeof(char)*10);
buffer_t buffer;
init(&buffer, 5);
char delimiter[] = "[";
char *ptr;
int i;
ptr = strtok(input, delimiter);
for (i = 0; i < 5; i++) {
sprintf(string_buffer,"[%s", ptr);
printf("push: %s", string_buffer);
// works but with missing character
push(&buffer, ptr);
// outputs the last element to the queue?
push(&buffer, string_buffer);
ptr = strtok(NULL, delimiter);
}
printf("\n");
for (i = 0; i < 5; i++) {
printf("pop from queue: %s\n", popqueue(&buffer));
}
}
使用sprintf的输出:
push: [MVOLT]
push: [S1]
push: [M1]40.05
push: [S1]
push: [M2]39.95
pop from queue: [M2]39.95
pop from queue: [M2]39.95
pop from queue: [M2]39.95
pop from queue: [M2]39.95
pop from queue: [M2]39.95
正如我所猜测的,您有一个指针数组,并且只存储指针 当你这样做的时候
push(&buffer, string_buffer);
将指针传递给字符串缓冲区数组的第一个元素。此指针将始终相同
一种可能的解决方案是使用非标准但常用的strdup函数动态创建新字符串:
push(&buffer, strdup(string_buffer));
请注意,这要求您在使用完指针后释放它,否则将导致内存泄漏。我猜,因为您没有显示包含推送功能的指针,所以您只存储一个指针。存储一个指针,这样一个缓冲区将存储指向同一个缓冲区的同一指针。show push和pop如何?我链接了代码,但我也将包含它。@有意义的程序员,我尝试通过将ptr-1存储到缓冲区来将指针向左移动,但这似乎只适用于第一次推。buffer->element[索引]=数据;只复制指针,而不复制它指向的字符串。好主意,但这似乎有些过分。我如何将指向新字符串的指针从缓冲区中释放出来?@Julian将popqueue返回的指针存储在变量中,并在打印后将其传递给free。@Julian overkill-否。正确功能的代码,然后地址overkill。
push(&buffer, strdup(string_buffer));