文件分析器 - 如何读取行

时间:2014-10-10 01:12:14

标签: c++ parsing

我正在尝试从stdin实现OpenGL中的行扫描转换,其中列出了行结束点,如下所示:

L 0, 0, 150, 150
C 200 300
L -20, 40, 22, 55
[...]
Z

[...]只是更相同,而Z字符是一个方便的终止操作符,尽管文件末尾也可以工作。 L和C分别表示用于绘制线条/圆圈的点/数据集。

这是我正在进行的解析器(包括所有正在使用的函数的库):

void parseFile ()
{

ifstream lines;
lines.open("C:/Users/Me/Desktop/lines.txt");
string currentLine = 0;

while(getline(lines, currentLine))
{

    switch(currentLine[0] = 'L')
    {
    string coordLine = currentLine.substr(1, currentLine.length());
    while (getline(lines, coordLine, ',')){
        for(int i = 0; i < coordLine.length(); i++) {
            char* c = 0;
            *(c+i) = coordLine[i];
            atoi(c);
            cout << c;
        }
        return;
    }

    }

    switch(currentLine[0] = 'Z') {
    break;
    }

    switch(currentLine[0] = 'C') {
    //Similar implementation to line case when resolved
    }

}

}

我试图仅将整数值(没有逗号和L / C / Z分隔符)读入数组,因此我可以简单地使用它们在OpenGL中进行绘制。但是,我在阅读和存储方面遇到了一些困难。正如您所看到的,我的算法方法是根据行开头的字母字符进行切换,然后将行字符串缩减为剩余值,并尝试通过它们。但是,我有一个不可能的时间尝试将值从我定义的坐标线转换为整数。

简而言之,我的问题是:我的方法是否有意义?与我计划实施的单独阵列方法相比,为OpenGL绘图使用存储这些坐标的更简单方法是什么?最后,我如何将文件的行转换为适当的整数进行存储?

1 个答案:

答案 0 :(得分:2)

您当前的代码存在许多问题。我提供了一个如何解析这个问题的例子:

void parseFile()
{
    ifstream lines;
    lines.open("test.txt");
    string currentLine; // Do NOT make this = 0 it will cause a crash!

    while(getline(lines, currentLine))
    {
        // no need to process blank lines
        // this also fixes potential crash
        // when you check the first character
        if(currentLine.empty())
            continue;

        // recommend std::stringstream for parsing strings
        std::istringstream iss(currentLine); // turn line into stream

        char type; // L, C or Z

        if(!(iss >> type)) // ALWAYS check for errors
            continue;

        // Your switch was incorrectly formed
        switch(type)
        {
            case 'L':
            {
                char comma;
                int x0, y0, x1, y1;

                // read the numbers skipping the commas
                if(!(iss >> x0 >> comma >> y0 >> comma >> x1 >> comma >> y1))
                {
                    // ALWAYS check for errors
                    std::cerr << "ERROR: Failed to read L: " << currentLine << std::endl;
                    continue;
                }

                // do something with coordinates (x0, y0, x1, y1) here
                std::cout << "(" << x0 << ", " << y0 << ", " << x1 << ", " << y1 << ")" << '\n';

                break;
            }
            case 'C':
            {
                break;
            }
            case 'Z':
            {
                break;
            }
            default:
                std::cerr << "ERROR: Unrecognized type: " << currentLine << std::endl;
        }
    }
}

注意:不要忘记错误检查。

希望有所帮助。