用c ++

时间:2016-09-19 06:29:39

标签: c++ parsing

我想构建一个日志浏览器。我需要有效编码。给出了一个简单的解析代码。 如果此代码没有问题或者有任何改进,请告诉我。 同样程序中的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;
    }
}

1 个答案:

答案 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;
}