如何从一个长的void*中获取每个char*?

huangapple go评论61阅读模式
英文:

How to get each char* from a long void*

问题

在C++中,您可以使用正则表达式或其他方法将void * 中的日志拆分为char*。以下是示例代码:

#include <stdio.h>
#include <cstdlib>
#include <cstring>
#include <string.h>
#include <stdlib.h>
#include <regex>

int main()
{
    void *logs = malloc(1024);
    char eachLog[100][100];
    if (logs == NULL) {
        printf("malloc failed\n");
        return -1;
    }

    memcpy(logs, "2023/05/29 10:12:16 638377 [ debug] this is\n 1st log\n", 53);
    memcpy((char*)logs + 53, "2023/05/29 10:12:16 638378 [   err] this is 2nd log\n", 52);
    memcpy((char*)logs + 105, "2023/05/29 10:12:16 638379 [  info] this is 3rd log\n", 52);

    // 使用正则表达式将日志拆分到eachLog数组中
    std::regex pattern(R"(\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \d+ \[[^\]]+\] (.*))");
    std::cmatch matches;
    const char *logsPtr = (const char *)logs;
    int logIndex = 0;

    while (std::regex_search(logsPtr, matches, pattern)) {
        if (logIndex < 100) {
            strcpy(eachLog[logIndex], matches[1].str().c_str());
            logsPtr = matches.suffix().first;
            logIndex++;
        }
    }

    free(logs);
    logs = NULL;
    return 0;
}

请注意,此示例使用正则表达式将日志拆分到eachLog 数组中,确保您的编译器支持C++正则表达式库。

英文:

I have a void * in c++, it contains many logs, but we do not know the length of each log. how can I split it to char*, using regular expression or some other methods.

#include &lt;stdio.h&gt;
#include &lt;cstdlib&gt;
#include &lt;cstring&gt;
#include &lt;string.h&gt;
#include &lt;stdlib.h&gt;
int main()
{
    void *logs = malloc(1024);
    char eachLog[100][100];
    if (logs == NULL) {
        printf(&quot;malloc failed\n&quot;);
        return -1;
    }

    memcpy(logs, &quot;2023/05/29 10:12:16 638377 [ debug] this is\n 1st log\n&quot;, 53);
    memcpy((char*)logs + 53, &quot;2023/05/29 10:12:16 638378 [   err] this is 2st log\n&quot;, 52);
    memcpy((char*)logs + 105, &quot;2023/05/29 10:12:16 638379 [  info] this is 3th log\n&quot;, 52);

    /* the logs may be like this:
    2023/05/29 10:12:16 638377 [ debug] this is\n 1st log\n2023/05/29 10:12:16 638378 [   err] this is 2st log\n2023/05/29 10:12:16 638379 [  info] this is 3th log\n
    
    What I want is:
    put the 1st log to eachLog[0];
    put the 2st log to eachLog[1];
    put the 3st log to eachLog[2];
    */

    free(logs);
    logs = NULL;
    return 0;
}

答案1

得分: 0

以下是翻译好的部分:

C++代码中,读取类似您的日志文件(带有杂乱的换行符)的代码如下所示(无void*,无显式手动内存管理,所有这些都由std::string和std::vector完成

在线演示:https://onlinegdb.com/peAvoAb0k

#include <sstream>
#include <iostream>
#include <string>
#include <regex>

using namespace std::string_literals;

// 允许日志行中的额外换行符
std::istringstream log_file
{
    "2023/05/29 10:12:16 638377 [ debug] this is\n 1st log\n"
    "2023/05/29 10:12:16 638378 [   err] this is 2st log\n"
    "2023/05/29 10:12:16 638379 [  info] this is 3th log\n"
};

std::vector<std::string> load(std::istream& file)
{
    // 在此处调试正则表达式:https://regex101.com/r/nt4FUG/1
    // 创建一个可以识别行的“标题”的正则表达式
    // 我现在保留了组(),以提高可读性(它们不是必需的)
    static std::regex rx{"^(\\d{4})\\/(\\d{2})\\/(\\d{2})\\s+(\\d{2}):(\\d{2}):(\\d{2})\\s+(\\d+)\\s+\\[\\s+\\w+\\]\\s+"};
    std::string line;
    std::vector<std::string> lines;

    while (std::getline(file, line))
    {
        // 如果存在标题,则找到一个新的日志条目
        if (std::regex_search(line, rx))
        {
            lines.push_back(line);
        }
        else
        {
            // 未找到标题,将读取的行添加到上次读取的最后一个日志行
            // 如果要保留换行符,可以使用以下行:lines.back() += ("\n"s + line);
            lines.back() += line;
        }
    }

    return lines;
}

int main()
{
    auto log = load(log_file);

    for (const auto& line : log)
    {
        std::cout << line << "\n";
    }

    return 0;
}
英文:

In C++ code to read a log file like yours (with stray newlines) would look something like this (no void*, no explicit manual memory managment, that is all done by std::string & std::vector)

Online demo : https://onlinegdb.com/peAvoAb0k

#include &lt;sstream&gt;
#include &lt;iostream&gt;
#include &lt;string&gt;
#include &lt;regex&gt;
using namespace std::string_literals;
// allow for extra newlines in log lines
std::istringstream log_file
{
&quot;2023/05/29 10:12:16 638377 [ debug] this is\n 1st log\n&quot;
&quot;2023/05/29 10:12:16 638378 [   err] this is 2st log\n&quot;
&quot;2023/05/29 10:12:16 638379 [  info] this is 3th log\n&quot;
};
std::vector&lt;std::string&gt; load(std::istream&amp; file)
{
// debug regexes here : https://regex101.com/r/nt4FUG/1
// make a regex that recognizes the &quot;header&quot; of a line
// I left the groups () in for readability for now (they are not necessary) 
static std::regex rx{&quot;^(\\d{4})\\/(\\d{2})\\/(\\d{2})\\s+(\\d{2}):(\\d{2}):(\\d{2})\\s+(\\d+)\\s+\\[\\s+\\w+\\]\\s+&quot;};
std::string line;
std::vector&lt;std::string&gt; lines;
while (std::getline(file,line))
{
// if there is a header then a new log entry is found
if (std::regex_search(line, rx))
{
lines.push_back(line);
}
else
{
// no header found, add the read line to the last log line read
//lines.back() += (&quot;\n&quot;s + line); if you want to retain newlines
lines.back() += line;
}
}
return lines;
}
int main()
{
auto log = load(log_file);
for (const auto&amp; line : log)
{
std::cout &lt;&lt; line &lt;&lt; &quot;\n&quot;;
}
return 0;
}

huangapple
  • 本文由 发表于 2023年6月26日 13:52:30
  • 转载请务必保留本文链接:https://go.coder-hub.com/76553843.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定