Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/61.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 带sprintf的环形缓冲区_C_String_Buffer_Strtok - Fatal编程技术网

C 带sprintf的环形缓冲区

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

我正在尝试创建一个ringbuffer,并用拆分字符串元素数组填充它。缓冲区代码取自,运行良好

以下是我的主要任务和缓冲区实现:

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