我正在编写一个程序来读取文件中的文本,我需要打印出每个数字出现在文件中的位置。例如,.txt文件如下所示:
one
two one two
three three two one
我的输出应该如下:
one: 0, 2, 7
two: 1, 3, 6
three: 4, 5
一切正常,直到我尝试显示string,list(int)类型的映射,然后我得到整个“”与'operator<<'“错误不匹配。 这是我的代码,非常感谢任何帮助,谢谢!
#include <iostream>
#include <fstream>
#include <string>
#include <map>
#include <list>
#include <vector>
using namespace std;
int main()
{
ifstream is("input.txt");
if (is.fail())
{
cout << "File I/O error!" << endl;
exit(1);
}
map<string, list<int> > m;
string word;
vector<string> v;
list<int> l, x, y;
while (is >> word)
{
v.push_back(word);
}
for (unsigned int i = 0; i < v.size(); ++i)
{
if (v[i] == "one")
l.push_back(i);
else if (v[i] == "two")
x.push_back(i);
else if (v[i] == "three")
y.push_back(i);
}
m["One"] = l;
m["Two"] = x;
m["Three"] = y;
for (map<string, list<int> >::iterator i = m.begin(); i != m.end(); ++i)
cout << (*i).first << ", " << (*i).second << endl;
return 0;
}
答案 0 :(得分:4)
问题是当您尝试输出(*i).second
时。由于i
类型为map<string, list<int> >::iterator
(*i).second
,因此list<int>
和c++
不知道如何输出它。
您有两个选项 - 重载ostream& operator<<(ostream& out, const list<int>& l)
或使用内循环逐个输出元素。我个人推荐第二个选项,因为重载操作员这种“流行”类型可能是危险的。
答案 1 :(得分:1)
最简单的解决方案:
// !!! DO NOT DO THIS AT HOME OR AT ALL !!!
namespace std {
template <typename T, typename A>
ostream& operator<<(ostream& out, list<T, A> const& l) {
if (l.empty()) { return out << "[]"; }
out << '[';
bool first = true;
for (auto const& t: l) {
if (first) { first = false; } else { out << ", "; }
out << t;
}
return out << ']';
} // operator<<
} // namespace std
不幸的是......严格禁止这样做(您只能在std
命名空间中专门化现有模板,而不是添加任何重载。)
因此,最符合标准的解决方案是:
std::ostream&
)随意笨拙地婊子......
自定义流to get you started的示例:
namespace project {
class OStream {
public:
explicit OStream(std::ostream& out): _out(out) {}
template <typename T>
OStream& operator<<(T const& t) { print(*this, t); return *this; }
template <typename T>
void push(T const& t) { _out << t; }
private:
std::ostream& _out;
}; // class OStream
// Generic Operator (directly forwards to `std::ostream`)
template <typename T>
void print(OStream& out, T const& t) { out.push(t); }
// STL Containers
template <typename It>
void print_range(OStream& out, It begin, It end) {
if (begin == end) { out << "[]"; return; }
out << '[' << *begin;
for (++begin; begin != end; ++begin) { out << ", " << *begin; }
out << ']';
} // push_range
template <typename T, typename A>
void print(OStream& out, std::list<T, A> const& l) {
print_range(out, l.begin(), l.end());
} // operator<<
} // namespace project
// usage
int main() {
std::list<int> example = { 1, 2, 3, 4 };
project::OStream(std::cout) << example << "\n";
}
注意:除了创建自定义流之外,还有其他解决方案,例如在您需要打印列表的地方复制粘贴std::copy(example.begin(), example.end(), std::ostream_iterator<int>(std::cout, ", "));
,但我还没有遇到另一个方便的。 < / p>