gpt4 book ai didi

c - 带 sprintf 的环形缓冲区

转载 作者:行者123 更新时间:2023-11-30 14:34:36 32 4
gpt4 key购买 nike

我正在尝试创建一个环形缓冲区并用一系列分割字符串元素填充它。 缓冲区代码取自here并且效果很好。

这是我的主要和缓冲区实现:

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


}

当我将 ptr 元素传递给推送函数时,一切正常。但是,如果我使用 sprintf 添加缺少的字符,我只能得到最后一个元素。 sprintf 正在做什么触发此行为?

直接输入 ptr 的输出:

push: [MVOLT]
push: [S1]
push: [M1]40.05
push: [S1]
push: [M2]39.95

pop from queue: MVOLT]
pop from queue: S1]
pop from queue: M1]40.05
pop from queue: S1]
pop from queue: M2]39.95

使用 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);

您将一个指针传递给string_buffer数组的第一个元素。该指针将始终相同。

一种可能的解决方案是使用非标准(但常用)strdup 函数动态创建新字符串:

push(&buffer, strdup(string_buffer));

请注意,这需要您在使用完指针后释放指针,否则会出现内存泄漏。

关于c - 带 sprintf 的环形缓冲区,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58916791/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com