我想构建一个日志浏览器。我需要有效编码。给出了一个简单的解析代码。 如果此代码没有问题或者有任何改进,请告诉我。 同样程序中的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;
}
}
答案 0 :(得分:3)
您的代码有效,但没有边界检查。如果文件中的行长于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;
}