【问题标题】:Splitting text file on '=' delimiter line by line C++逐行分割'='分隔符上的文本文件C++
【发布时间】:2017-03-25 22:15:59
【问题描述】:

我正在尝试在 C++ 中制作字典,但无法在“=”分隔符上拆分文本文件。理想情况下,它将是两个数组。我想将行的“=”的左侧放入array[0],将右侧放入array[1],然后通过预制使用array[0]作为键,使用array[1]作为值插入功能,例如。字典.插入(数组 [0],数组 [1])。我已经构建了字典逻辑,但是在拆分行时遇到了麻烦。

这是我的(糟糕的)代码,它没有使用等号作为分隔符,因此将“=”放入数组 [1]:

int main() {

    Dictionary englishToEsperanto;

    ifstream infile("Dictionary.txt");

    string line;
    string arr[2];

    if (infile.is_open())
    {
        while (getline(infile, line))
        {
            int i = 0;
            stringstream ssin(line);
            while (ssin.good() && i < 2) {
                ssin >> arr[i];
                ++i;
            }
            for (i = 0; i < 2; i++) {
                cout << arr[i] << ' ';
            }
                cout << endl;
        }

        infile.close();
    }
    else
    {
        cout << "Error opening file";
    }


    return 0;
}

这是文本文件的前几行:

aback, to take = surprizi.
abaft = posta parto.
abandon = forlasi.
abase = humiligi. [error in book: humilgi]
abash = hontigi.
abate (lower) = mallevi.
abate (speed) = malakceli.
abbey = abatejo.
abbot = abato.
abbreviate = mallongigi.
abdicate = demeti la reĝecon.
abdomen = ventro.

感谢收看。

【问题讨论】:

  • 您可以使用std::getline(infile, word, '=') 读取密钥并使用std::getline(infile, word); 获取该行的其余部分。

标签: c++ arrays dictionary


【解决方案1】:

您可以使用std::string 类的标准数据成员函数来执行任务。结果对可以存储在标准类std::vector

这是一个演示程序

#include <iostream>
#include <string>
#include <vector>
#include <utility>
#include <cstring>

std::string & trim( std::string &s )
{
    std::string::size_type n = 0;

    while ( n < s.size() && std::isspace( ( unsigned char )s[n] ) ) n++;

    s.erase( 0, n );

    n = s.size();

    while ( n != 0 && std::isspace( ( unsigned char )s[n-1] ) ) n--;

    s.erase( n );
}   

int main() 
{
    const char * s[] =
    {
        "aback, to take = surprizi.",
        "abaft = posta parto.",
        "abandon = forlasi.",
        "abase = humiligi. [error in book: humilgi]",
        "abash = hontigi.",
        "abate (lower) = mallevi.",
        "abate (speed) = malakceli.",
        "abbey = abatejo.",
        "abbot = abato.",
        "abbreviate = mallongigi.",
        "abdicate = demeti la reĝecon.",
        "abdomen = ventro.",
    };


    std::vector< std::pair<std::string, std::string>> dictionary;

    for ( std::string line : s )
    {
        auto n = line.find( '=' );

        std::string key, description;

        if ( n == std::string::npos )
        {
            key = line;
        }
        else
        {
            key = line.substr( 0, n );
            description = line.substr( n + 1 );
        }

        trim( key ); trim( description );

        dictionary.push_back( { key, description } );
    }


    for ( const auto &p : dictionary )
    {
        std::cout << p.first << '\t' << p.second << std::endl;
    }

    return 0;
}

它的输出是

aback, to take  surprizi.
abaft   posta parto.
abandon forlasi.
abase   humiligi. [error in book: humilgi]
abash   hontigi.
abate (lower)   mallevi.
abate (speed)   malakceli.
abbey   abatejo.
abbot   abato.
abbreviate  mallongigi.
abdicate    demeti la reĝecon.
abdomen ventro.

【讨论】:

    【解决方案2】:

    如果您可以访问 Boost,Boost.Tokenizer 就是您要找的。 你可以找到一个例子here。 这将返回一个字符串向量。

    否则,您可以使用std::string::find,并按照以下方式实现:

    int indOfDelimiter=line.find('=');
    std::string Key = line.substr(0,indOfDelimiter);
    std::string Value = line.substr(indOfDelimiter+1);
    

    在您的示例中,“=”之前和之后都有空格。您可能希望通过更改上面代码中的分隔符来摆脱这些:

    const char *delimiter = " = ";
    int indOfDelimiter=line.find(delimiter);
    std::string Key = line.substr(0,indOfDelimiter);
    std::string Value = line.substr(indOfDelimiter+3);
    

    【讨论】:

    • 我认为Boost.Tokenizer 对于每行只有两个项目可能有点矫枉过正。
    • @ThomasMatthews 可能是的,但它是一个干净而强大的工具,值得一看。
    【解决方案3】:

    按照@Thomas 在评论中的建议,将'=' 设置为第一个getline 的分隔符,将第二个getline 设置为默认分隔符换行Demo.

    string before_equal, after_equal;
    string arr[2];
    while (getline(cin, before_equal, '=') && getline(cin, after_equal))
    {
        stringstream ssin1(before_equal);
        stringstream ssin2(after_equal);
        if (ssin1.good() && ssin2.good()) {
            ssin1 >> arr[0];
            ssin2 >> arr[1];
        }
        else continue;
        cout << arr[0] << ' ' << arr[1];
        cout << endl;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-09-21
      • 1970-01-01
      • 1970-01-01
      • 2015-07-06
      • 1970-01-01
      • 2015-05-21
      • 2012-10-21
      • 2011-12-20
      相关资源
      最近更新 更多