英文:
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 <stdio.h>
#include <cstdlib>
#include <cstring>
#include <string.h>
#include <stdlib.h>
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 2st log\n", 52);
memcpy((char*)logs + 105, "2023/05/29 10:12:16 638379 [ info] this is 3th log\n", 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 <sstream>
#include <iostream>
#include <string>
#include <regex>
using namespace std::string_literals;
// allow for extra newlines in log lines
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)
{
// debug regexes here : https://regex101.com/r/nt4FUG/1
// make a regex that recognizes the "header" of a line
// I left the groups () in for readability for now (they are not necessary)
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 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() += ("\n"s + line); if you want to retain newlines
lines.back() += line;
}
}
return lines;
}
int main()
{
auto log = load(log_file);
for (const auto& line : log)
{
std::cout << line << "\n";
}
return 0;
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论