从文本文件C ++中删除或忽略重复的行

时间:2012-11-12 16:27:55

标签: c++

目前我正在尝试读取文本文件并忽略其中的重复行。这是我到目前为止所做的代码示例

string filename;
            cout<<"Please enter filename: "<<endl;
            cin>>filename;
            ifstream inFile(filename.data());

            typedef std::map<std::string, int> line_record;
            line_record lines;
            int line_number = 1;

            if(inFile.is_open())
            {
                while(std::getline(inFile, line))
                {   
                    line_record::iterator existing = lines.find(line);
                    if(existing != lines.end())
                    {
                        existing->second = (-1);
                    }
                    else
                    {
                        lines.insert(std::make_pair(line,line_number));
                        ++line_number;
                        getline(inFile,line);
                        cout<<line<<endl;
                        noOfLine++;    
                    }

                }    
            }else
            {
                cout<<"Error opening file! Please try again!"<<endl;
            }
            cout<<"\n"<<noOfLine<<" record(s) read in successfully!\n"<<endl;

文本文件(如下):

Point2D, [3, 2]
Line3D, [7, 12, 3], [-9, 13, 68]
Point3D, [1, 3, 8]
Line2D, [5, 7], [3, 8]
Point2D, [3, 2]
Line3D, [7, -12, 3], [9, 13, 68]
Point3D, [6, 9, 5]
Point2D, [3, 2]
Line3D, [70, -120, -3], [-29, 1, 268]
Line3D, [25, -69, -33], [-2, -41, 58]
Point3D, [6, 9, -50]

但我得到的结果是:

Line3D, [7, 12, 3], [-9, 13, 68]
Line2D, [5, 7], [3, 8]
Point3D, [6, 9, 5]
Line3D, [25, -69, -33], [-2, -41, 58]
Point3D, [6, 9, -50]

任何帮助?谢谢!

3 个答案:

答案 0 :(得分:2)

您的代码会读取并丢弃循环中的下一行:

lines.insert(std::make_pair(line,line_number));
++line_number;
// HERE
getline(inFile,line);
cout<<line<<endl;
noOfLine++;

基本上,程序的输出包含程序丢弃的行

你应该通过“阅读”循环而不产生任何输出,然后浏览map,并打印出行的内容,并找到它们所在的行号。

答案 1 :(得分:0)

我只是编辑了一些东西而且它的工作如果(myfile.is_open())

{

            while(getline(myfile, line)){


                line_record::iterator existing = lines.find(line);

                if(existing != lines.end())
                {
                    existing->second = (-1);




                }
                else
                {

                    lines.insert(make_pair(line,line_number));
                    ++line_number;
                    cout<<line<<endl;

                    count++;
                }



            }

            cout << "its -- > "<<count <<" record"<< endl;




    myfile.close();

}

`

答案 2 :(得分:0)

这是此问题的完整解决方案:

#include <string>
#include <iostream>
#include <fstream>
#include <map>
#include <vector>
#include <algorithm>
#include <iterator>
using namespace std;

// we gonna read each line to map<string, int>
// which will be ordered by its strings by default nature, not line numbers
// then read this map to the vector and sort it by line numbers as it should be for output.txt

typedef pair<string, int> vecpair;

int main(int argc, char* argv[])
{
    if(argc < 2)
    {
        cout << "Missing input filename" << endl;
        exit(1);
    }
    else
    {
        ifstream infile(argv[1], ios::in);
        ofstream outfile("output.txt", ios::out);

        if(!infile)
        {
            cout << "File " << argv[1] << "could not be opened" << endl;
            exit(1);
        }

        // map of input file string lines
        map<string, int> records;
        int line_number{0};

        for(string line{}; getline(infile, line); line_number++)
        {
            auto entry = make_pair(line, line_number);
            auto pair = records.insert(entry);
        }

        infile.close();

        /*
        // map to the outfile sample as part of debugging
        if(records.empty())
        {
            outfile << "Empty records" << endl;
        }
        else
        {
            for(auto iter = records.begin(); iter != records.end(); iter++)
            {
                outfile << iter->first << "\t" << iter->second << endl;
            }
        }
        */

        // create an empty vector of pairs
        vector<vecpair> vec;

        // copy key-value pairs from the map to the vector
        copy(records.begin(), records.end(), back_inserter<vector<vecpair>>(vec));

        // sort the vector by increasing order of its pair's second value
        // if second value are equal, order by the pair's first value
        sort(vec.begin(), vec.end(), [](const vecpair& l, const vecpair& r)
        {
            if(l.second != r.second)
                return l.second < r.second;
            return l.first < r.first;
        });


        // output vector to outfile.txt
        if(vec.empty())
        {
            outfile << "Empty records" << endl;
        }
        else
        {
            for(auto const &vecpair : vec)
            {
                //outfile << vecpair.first << "\t" << vecpair.second << endl;
                outfile << vecpair.first << endl;
            }
        }

        outfile.close();
        return 0;
    }
}