读取同一行中用双引号括起来的文本,并拒绝在不同行上关闭的双引号

时间:2018-03-02 22:55:07

标签: c++

我正在尝试检测文件中的字符串文字。我想只读给定任意字符串的双引号中的内容。我怎样才能做到这一点?这是我的代码:

#include <iostream>
#include <fstream>

using namespace std;

int main()
{
    ifstream fin;
    fin.open("badstr.txt");
    string comment;
    string strVal;

    char c;
    bool inString = false;
    int lineCount = 0;
    while (fin.get(c))
    {
        if(c == '\n') // get the Line count
        {
            lineCount ++;
        }
        if(c == '#')
        {
            getline(fin,comment);
            continue;
        }
        if(c == '\"')
        {
            //**************this is where I need help**************
            /*
            I would like to read the next character after the opening double quote and the character before the closing double quote;
            */
        }
        if(inString) {
          strVal += c;
        }
    }
    cout << "\n Number of lines : " << lineCount << endl;
}

1 个答案:

答案 0 :(得分:0)

尝试这样的事情:

#include <iostream>
#include <fstream>
#include <string>
#include <limits>

int main()
{
    std::ifstream fin;
    std::string strVal;
    char c;
    bool inString = false;
    int lineCount = 0;

    fin.open("badstr.txt");
    if (!fin.is_open())
    {
        std::cout << "Cannot open file" << endl;
        return 0;
    }

    while (fin.get(c))
    {
        if (c == '\r')
        {
            // bare-CR or CRLF?
            if (!fin.get(c))
                break;

            if (c == '\n')
            {
                // CRLF line break
                ++lineCount;

                // you decide if a line break in the middle of a quoted string is valid or not...
                if (inString)
                    strVal += c;

                continue;
            }

            // bare-CR, you decide if you want to treat it as a line break or not...

            // ++lineCount;

            if (inString)
            {
                strVal += '\r'; // or '\n' if line break
                strVal += c;
            }

            continue;
        }

        if (c == '\n')
        {
            // bare-LF line break
            ++lineCount;

            // you decide if a line break in the middle of a quoted string is valid or not...
            if (inString)
                strVal += c;

            continue;
        }

        if (c == '#')
        {
            if (inString)
                strVal += c;
            else
                fin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

            continue;
        }

        if (c == '\"')
        {
            if (!inString)
            {
                inString = true;
            }
            else
            {
                inString = false;
                // use strVal as needed...
                strVal = "";
            }

            continue;
        }

        if (c == '\\')
        {
            if (inString)
            {
                if (!fin.get(c))
                    break;

                if (c == '\\')
                {
                    strVal += c;
                    continue;
                }

                if (c == '\"')
                {
                    strVal += c;
                    continue;
                }

                // handle other escape sequences as needed...
            }

            continue;
        }

        if (inString)
            strVal += c;
    }

    std::cout << "\n Number of lines : " << lineCount << std::endl;
    return 0;
}

话虽如此,如果引用字符串中间的换行符无效,您可以考虑另一种方法:

#include <iostream>
#include <fstream>
#include <string>

int main()
{
    std::ifstream fin;
    std::string line, strVal;
    std::string::size_type start, end;
    int lineCount = 0;

    fin.open("badstr.txt");
    if (!fin.is_open())
    {
        std::cout << "Cannot open file" << endl;
        return 0;
    }

    while (std::getline(fin, line))
    {
        ++lineCount;

        start = 0;
        do
        {
            start = line.find('\"', start);
            if (start == std::string::npos)
                break;

            ++start;
            end = start;

            do
            {
                end = line.find_first_of("\\\"", end);
                if (end == std::string::npos)
                {
                    end = line.length();
                    break;
                }

                if (line[end] == '\"')
                {
                    strVal = line.substr(start, end-start);
                    // use strVal as needed...
                    ++end;
                    break;
                }

                // handle escape sequence as needed...

                end += 2;
            }
            while (true);

            start = end;
        }
        while (true);
    }

    std::cout << "\n Number of lines : " << lineCount << std::endl;
    return 0;
}