0
votes

I am getting this error:

no operator ">>" matches these operands -- operand types are: std::__1::ifstream >> std::__1::pair<char, int>

when I use pair.

However, after adding #include <string> from this thread, I still cannot fix this issue.

How can I resolve the error?

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

using namespace std;

int main() {
    ifstream fin("test.in");
    ofstream fout("test.out");

    int n; fin >> n;
    pair<char, int> data[1000];

    for(int i = 0; i < n; i++) {
        fin >> data[i];
    }

    for(int i = 0; i < n; i++) {
        fout << data[i];
    }
}
4
There are no input or output operators for pair.Barmar
How do you think a pair should be formatted and parsed?Barmar
should char there be treated as a character or as a number?Swift - Friday Pie

4 Answers

1
votes

There are no overloads for the stream extraction (>>) and insertion (<<) operators for std::pair. However, it's easy enough to define them.

You didn't specify the format of your files. Are you trying to read in char and int pairs? By default, the >> operator for the fundamental types will use whitespace as the delimiter. So this will work for that case:

std::istream& operator>>(std::istream& is, std::pair<char, int>& p)
{
    is >> p.first >> p.second;
    return is;
}

If you don't have a whitespace delimiter, then it gets a bit more complicated. You can use std::getline to read in a line and do some parsing yourself. The << operator can be defined in a similar way:

std::ostream& operator<<(std::ostream& os, const std::pair<char, int> &p)
{
    os << p.first << " " << p.second << "\n";
    return os;
}

Note that I'm outputting a whitespace between the first and second member for each pair, plus a newline at the end. You can tweak this as you like.

1
votes

Operators are not magic. There is no definition for operators << or >> that take a pair as an operand. So, without using extra libraries, or defining the operators yourself, then you can resolve this by accessing the first and second fields yourself, eg:

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

using namespace std;

int main() {
    ifstream fin("test.in");
    ofstream fout("test.out");

    int n; fin >> n;
    pair<char, int> data[1000];

    for(int i = 0; i < n; i++) {
        fin >> data[i].first;
        fin >> data[i].second;
    }

    for(int i = 0; i < n; i++) {
        fout << data[i].first;
        fout << data[i].second;
    }
}
1
votes

If the data format is strict enough, use struct and operator overloading for stream insertion and stream extraction. If you only need integers from a file, don't bother with char c delimiter and let >> do their job.

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

using namespace std;

struct Data {
private:
  int num;
  char c;

public:
  std::ifstream &operator<<(std::ifstream &fin)
  {
    fin >> num >> c;
    return fin;
  }
  std::ofstream &operator>>(std::ofstream &fout)
  {
    fout << num << c;
    return fout;
  }
};

int main()
{
  ifstream fin("fin.txt");
  ofstream fout("fout.txt");

  int n;
  fin >> n;
  Data data[5];

  for (int i = 0; i < n; i++) {
    data[i] << fin;
  }

  for (int i = 0; i < n; i++) {
    data[i] >> fout;
  }
}
0
votes

You need to include utility for pair.

You are getting error of >> because operator >> is not overloaded for pair. May be you want to access first or second of the pair.

Also, there is no overload of << for pair.

Reference: https://en.cppreference.com/w/cpp/utility/pair