我想构建一个日志浏览器。为此我需要有效地编码。给出了一个简单的解析代码。 请让我知道这段代码是否可以或需要进行任何改进。 下面给出的程序中的 strtok(o,delim) 函数也不清楚。所以请向我解释一下它的功能。
// parsing ex.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using std::cout;
using std::endl;
#include <fstream>
using std::ifstream;
#include <cstring>
const int MAX_CHARS_PER_LINE = 512;
const int MAX_TOKENS_PER_LINE = 20;
const char* const DELIMITER = " ";
int main()
{
// create a file-reading object
ifstream fin;
fin.open("C:\\Personal\\data.txt"); // open a file
if (!fin.good())
return 1; // exit if file not found
// read each line of the file
while (!fin.eof())
{
// read an entire line into memory
char buf[MAX_CHARS_PER_LINE];
fin.getline(buf, MAX_CHARS_PER_LINE);
// parse the line into blank-delimited tokens
int n = 0; // a for-loop index
// array to store memory addresses of the tokens in buf
const char* token[MAX_TOKENS_PER_LINE] = {}; // initialize to 0
// parse the line
token[0] = strtok(buf, DELIMITER); // first token
if (token[0]) // zero if line is blank
{
for (n = 1; n < MAX_TOKENS_PER_LINE; n++)
{
token[n] = strtok(0, DELIMITER); // subsequent tokens
if (!token[n]) break; // no more tokens
}
}
// process (print) the tokens
for (int i = 0; i < n; i++) // n = #of tokens
cout << "Token[" << i << "] = " << token[i] << endl;
cout << endl;
}
}
最佳答案
除了没有边界检查之外,您的代码可以正常工作。如果文件中的行长于 MAX_CHARS_PER_LINE
,它将失败。 while (!fin.eof()){...}
还容易出现其他错误。
使用std::string
可以轻松解决这个问题
如果一行包含超过 MAX_TOKENS_PER_LINE
个标记,该代码也会失败。您可以使用 std::vector
要进行改进,请使用 std::string
而不是字符数组。
使用 std::vector
而不是 C 样式数组。
使用std::stringstream
代替strtok
优点是您不必担心最大行长度或每行的最大标记数。
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
#include <vector>
const char CDELIMITER = ' ';
int main()
{
...
std::string buf;
//read the file line by line
while (std::getline(fin, buf))
{
//convert the line in to stream:
std::istringstream ss(buf);
//declare vector of string (instead of fixed array)
std::vector<std::string> vec;
//read the line, word by word
while (std::getline(ss, buf, CDELIMITER))
vec.push_back(buf);
for (size_t i = 0; i < vec.size(); i++)
std::cout << "Token[" << i << "] = " << vec[i] << "\n";
std::cout << "\n";
}
return 0;
}
关于c++ - 在 C++ 中有效地解析日志文件的文本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39566662/