带有文件 C++ 问题的嵌套 while 循环

Nested while loop with file c++ issues

我必须创建一个程序来获取 A 组文件中的字符串并将它们与 B 组的字符串进行比较,从而创建视频输出和与输出视频文件相同的结果。组文件的结构如下:Jhon Smith'\n'Fergus McDonald'\n'Elizabeth Harris'\n'。我有嵌套 while 循环的问题,最后一个检查 A 的名称是否等于 B 的名称似乎有效,但其他两个无效,内部循环第一次有效但另一个无效,if 条件对于第二组嵌套的 while 循环,似乎没有更多的工作,并且在文件元素的数量中重复所有文件的名称,反之亦然,我不明白什么是错的

#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <fstream>

using namespace std;

int main() {
    string As, Bs, Cs;
    ifstream A("Group_A.txt");
    ifstream B("Group_B.txt");
    ofstream C("Result.txt");

    if(!A)
    {
        cout<<"Group A does not exist!";
        return -1;
    }
    if(!B)
    {
        cout<<"Group B does not exist!!";
        return -1;
    }
    if(!C)
    {
        cout<<"Failed to create file!!";
        return -1;
    }

    C<<"Elements in A but not in B:"<<endl;
    while(getline (B,Bs))
    { 
      while(getline (A,As))
      { 
        if (As != Bs)
        {
            C<<As<<endl;
        }
      }
      A.clear();
      A.seekg(0);
    }
    A.close();
    B.close();
    C<<endl;

    A.open("Group_A.txt");
    B.open("Group_B.txt");
    C<<"Elements in B but not in A:"<<endl;
    while(getline (A,As))
    {
      while(getline (B,Bs))
      { 
        if (Bs != As)
        {
            C<<Bs<<endl;
        } 
      }
      B.clear();
      B.seekg(0);
    }
    A.close();
    B.close();
    C<<endl;

    A.open("Group_A.txt");
    B.open("Group_B.txt");
    C<<"Elements present in both A and B:"<<endl;
    while(getline (A,As))
    {
      while(getline (B,Bs))
      { 
        if (As == Bs)
        {
            C<<Bs<<endl;
        } 
      }
      B.clear();
      B.seekg(0);
    }

    A.close();
    B.close();
    C<<endl;
    C.close();

    ifstream res("Result.txt");
    while(res >> Cs)
    cout<<Cs<<endl;

     system ("PAUSE");
      return 0;
}
// write a function that load your file
template <class Itr>
void read_file(std::string const& name, Itr to) {
    std::ifstream in(name);
    for (std::string line; std::getline(in, line); *itr++ = std::move(line));
}

// load your files
std::set<std::string> a;
read_file("a.txt", std::inserter(a));
std::set<std::string> b;
read_file("b.txt", std::inserter(b));

// based on what you need use one of set algorithms
// from the standard library
// I assumeed you need the union of the two in the below code
std::vector<std::string> c;
std::set_union(a.begin(), a.end(), b.begin, b.end(), std::back_inserter(c));

// dump the result
std::ofstream out("c.txt");
std::copy(c.begin(), c.end(), std::ostream_iterator(out, "\n"));

问题:

foreach B in file B
    foreach A in file A
        if (A != B)
            output A 

假设文件 A 包含 1,2,3,文件 B 包含 2,3,4

测试将如下所示:

2 != 1: true, output 1
2 != 2: false, no output
2 != 3: true, output 3
3 != 1: true, output 1
3 != 2: true, output 2
3 != 3: false, no output
4 != 1: true, output 1
4 != 2: true, output 2
4 != 3: true, output 3

输出文件将包含 1,3,1,2,1,2,3

您要做的是构建文件 A 和 B 的集合交集(我们称之为 AnB)。这给了你第三个循环。 A 和 B 中的所有内容。

将AnB 与A 进行比较。因此,所有在A 中但不在AnB 中的东西都不可能在B 中。在 A 而不是 B。重复 B

或者您可以直接致电 std::set_intersection and std::set_difference

#include <iostream>
#include <fstream>
#include <set>
#include <vector>
#include <algorithm>
using namespace std;

// Not elegant, but it's pretty much what the OP was using
// and this isn't a question about proper file handling.
// Optimize as needed
bool readFile(const string &filename, set<string> &lines)
{
    ifstream input(filename.c_str());

    if (!input) // this will fail in a few cases
    {
        cout << "Group A does not exist!" << endl;
        return false;
    }

    string line;

    while (getline(input, line))
    {
        lines.insert(line);
    }
    return true;
}

void writeFile (ofstream & out,
                std::vector<string> & data,
                std::vector<string>::iterator stop,
                const std::string &message)
{
    // resizing the vectors the their actual used size makes output easy.
    data.resize(stop - data.begin());
    out << message << endl;
    for (std::vector<string>::iterator it = data.begin(); it != data.end(); ++it)
    {
        out << *it << endl;
    }
}

int main()
{
    set<string> Group_A;
    set<string> Group_B;
    ofstream Result("Result.txt");

    readFile("Group_A.txt", Group_A);
    readFile("Group_B.txt", Group_B);

    // Danger! Danger! Blows up if you do not preallocate
    // enough storage in vectors! Sized for worst case
    std::vector<string> AnB(Group_A.size() + Group_B.size());
    // really this should just be size of the larger list, but I'm lazy
    std::vector<string> AnotB(Group_A.size()); //sized for no intersection
    std::vector<string> BnotA(Group_B.size()); //sized for no intersection

    // use this to catch the true vector size after the std::set_* calls
    std::vector<string>::iterator stop;

    stop = std::set_intersection(Group_A.begin(), Group_A.end(),
                                 Group_B.begin(), Group_B.end(),
                                 AnB.begin());
    writeFile (Result, AnB, stop, "Intersection:");

    stop = std::set_difference(Group_A.begin(), Group_A.end(),
                               Group_B.begin(), Group_B.end(),
                               AnotB.begin());
    writeFile (Result, AnotB, stop, "A not B:");

    // note the exchange of A and B on the std::set_difference call
    stop = std::set_difference(Group_B.begin(), Group_B.end(),
                               Group_A.begin(), Group_A.end(),
                               BnotA.begin());
    writeFile (Result, BnotA, stop, "B not A:");
}