我对C没有多少经验。
我有一个小的C程序,它连接到几乎无限的文本流(25Mb/s)。
我想用zeromq将字符串的每一行作为单独的消息发送。
因此,我将每秒发送数千条消息,在发送每条消息之前,我想操纵通过套接字发送的字符串:
我先说:

Quote {0.0.0.0} XXX <1>A<2>B<3>C

我想要
XXX Quote <1>A<2>B<3>C

在一般意义上,我如何安全地做到这一点,以避免我遇到内存泄漏?我会有这样的东西(只是一个例子,main函数实际上是一个具有不同字符的永无止境的循环):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char* parse(const char* input) {

        char* output;
        char* input_copy = strdup(input);
        char* token;
        char* first;
        char* third;
        char* fourth;

        token = strtok(input_copy, " ");
        first = token;

        for (int i = 0; i < 3; i++)
        {
                token = strtok(NULL, " ");
                if (i == 1) third = token;
                if (i == 2) fourth = token;
        }

        asprintf(&output, "%s %s %s", third, first, fourth);
        return output;
        free(output);
}

int main(void)
{
        const char *a = "Quote {0.0.0.0} XXX <1>A<2>B<3>C";
        //SEND_MESSAGE(parse(a));
        return 0;
}

这行吗?

最佳答案

如果您知道(或者可以确定其特殊性),每一个最大值的大小是什么,您可以通过使用一个固定大小的缓冲区来消除所有内存泄漏的可能性。你说你的25米/秒的文本被分成几行,所以你大概是在使用一个面向行的输入函数(例如firstsecond)来读取流。在这种情况下,您也可以使用最大行长度(X4)来确保固定的缓冲区是足够的。
您正在使用third作为分隔符将标记化为fourthfgetsgetlinefirst,为什么不使用second?如果要使用third函数,只需将缓冲区作为参数传递。
如果您可以确定一个max,并且您正在标记fourth,那么您可以做一些简单的事情:

#include <stdio.h>

#define MAXC 1024

int main(void)
{
    const char *a = "Quote {0.0.0.0} XXX <1>A<2>B<3>C";
    char first[MAXC] = "",
         second[MAXC] = "",
         third[MAXC] = "",
         fourth[MAXC] = "";

    /* read a line from the stream and simply call sscanf */
    if (sscanf (a, " %s %s %s %s", first, second, third, fourth) == 4)
        printf ("%s %s %s\n", third, first, fourth);

    return 0;
}

space仅用于示例,根据需要将结果传递给zeromq)
示例使用/输出
$ ./bin/staticbuf
XXX Quote <1>A<2>B<3>C

(这样做的副作用是大大简化了代码,而且可能还会大大加快速度)。
如果您不能确定最大大小,那么您将陷入sscanf/parse的开销(或者使用POSIXspace并让它处理分配)。

关于c - C-安全地解析和发送大量无穷大字符串,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/39326245/

10-11 22:57
查看更多