C++,如何从文件中读取数据并插入容器:地图

C++, How to read data from file and insert in container: Map

本文关键字:插入 地图 数据 读取 文件 C++      更新时间:2023-10-16

我在用信息填充容器地图时遇到问题。我用操作员阅读了信息>>但它在我的二级 CDealer 中给了我这些错误。no operator ">>" matches these operandsbinary">>": no operator found which takes a right-hand operand of type 'const CStock'(or these is no acceptable conversion)我有三个类:CStock,有map<CStock, pair<unsigned, double>> Stock;的CDealer和有vector<CDealer*> Dealers;的CShop 如果有人能帮助我,我将不胜感激。

这是我在 CStock 中的运算符<<和>>

ostream &operator << (ostream &toStream, const CStock &S){
toStream << "Name Stock: " << S.m_strName_stock << " Producer: " << S.m_strProducer <<
"Date: " << S.Date;
return toStream;
}
istream &operator >> (istream &fromStream, CStock &S)
{return fromStream >> S.m_strName_stock >> S.m_strProducer >> S.Date;}

这是我在 CDealer 中<<和>>的运算符 `

ostream &operator << (ostream &toStream, CDealer &D) 
{
toStream << "Name Dealer: " << D.m_strName_Dealer << " Agent: " << D.m_strAgent <<
"Address: " << D.m_strAddress;
map<CStock, pair<unsigned, double>>::const_iterator it = D.Stock.begin();
while (it != D.Stock.end())
{
toStream << it->first <<it->second.first << it->second.second;
}
return toStream;
}
istream &operator >> (istream &fromStream, CDealer &D)
{
map<CStock, pair<unsigned, double>>::iterator it = D.Stock.begin();
fromStream >> D.m_strName_Dealer >> D.m_strAgent >> D.m_strAddress;
while (it!= D.Stock.end())
{fromStream >> it->first >> it->second.first >> it->second.second;}
return fromStream
}

这是带有参数的构造函数:文件名和这些运算符<<,>>

CShop::CShop(const string &fname)
{
CDealer c;
fstream File(fname, ios::in);
if (File.is_open())
{
File >> m_strNameShop;
File >> m_strCity;
while (File>>c)
{   
Dealers.push_back(new CDealer(c));
}
File.close();   
}
else
throw "ERROR! ";
}
ostream &operator << (ostream &toStream, const CShop &S)
{
toStream << "Name Shop: " << S.m_strNameShop << " City: " << S.m_strCity;
vector<CDealer* >::const_iterator it = S.Dealers.begin();

while (it != S.Dealers.end())
{
CDealer* dealerPtr = *it++;
toStream << *dealerPtr<< endl;
}
return toStream;
}
istream &operator >> (istream &fromStream, CShop &D)
{
return fromStream >> D.m_strNameShop >> D.m_strCity;
}

最后主要()

#include"CDealer.h"
#include"CShop.h"
#include<iostream>
#include<string>
#include <stdlib.h>  
#include<vector>
using namespace std;
int main()
{
CShop SS1("data.txt");
cout << SS1;
system("pause");
return 0;
}

istream &operator >> (istream &fromStream, CDealer &D)的实现 考虑不周。

该函数的目标是从输入流中读取数据并充实CDealer对象的内容。通常,operator<<operator>>函数协同工作,以便您可以使用operator>>读回您使用operator<<编写的内容。

从这个角度来看,即使是operator<<功能也需要改进。

这是一个只要字符串对象中没有空格就可以工作的实现。如果字符串对象中有空格,则需要更改代码。

std::ostream& operator<<(std::ostream &toStream, CDealer cosnt& D) 
{
// Write the name of the dealer, without any decorative text.
// Add a space character to the output so you can read the name back.
toStream << D.m_strName_Dealer << " ";
// Do the same for name of the agent and address.
toStream << D.m_strAgent << " ";
toStream << D.m_strAddress << " ";
// Write the number of items in Stock first.
// This will be necessary when reading the data.
toStream << D.Stock.size() << " ";
// Now write the Stock items, which spaces between each field you write.
map<CStock, pair<unsigned, double>>::const_iterator it = D.Stock.begin();
while (it != D.Stock.end())
{
toStream << it->first << " " << it->second.first << " " << it->second.second << " ";
}
return toStream;
}
std::istream &operator>>(std::istream &fromStream, CDealer &D)
{
// Read the name of the dealer.
fromStream >> D.m_strName_Dealer;
// Read the name of the agent.
fromStream >> D.m_strAgent;
// Read the address.
fromStream >> D.m_strAddress;
// Read the number of items.
size_t num;
fromStream >> num;
// Now read the Stock items.
for ( size_t i = 0; i < num; ++i )
{
// Obtained the types for key, val1, and val2 from
// the error message posted in a comment by OP.
CStock key;
int val1;
double val2;
fromStream >> key >> val1 >> valu2;
// Add the item to Stock.
D.Stock.insert(std::make_pair(key, std::make_pair(val1, val2)));
}
return fromStream
}

问题

该问题可以简化为以下情况:

#include <map>

int main(void) {
std::map<int, int> val;

auto it = val.begin();
it->first = 10;
}

std::map中的键值是const(键和值对定义为std::pair<const Key, T>),因此对于

map<CStock, pair<unsigned, double>>

我们有一个包含pairmap

std::pair<const CStock, pair<unsigned, double>>

这使得it->first

fromStream >> it->first >> it->second.first >> it->second.second;

aconst CStock并导致报告的错误。

这一切都是有道理的,因为map是按键排序的,所以如果你可以随时更改键,你想要的任何东西,map很快就会变得不连贯。

有关std::map的文档

溶液

没有简单的解决办法。你不能这样做。您必须制作项目,然后将它们放置在map中,或者使用emplace系列函数之一直接在map中构造它们。一旦它们进入map,您就可以更改值,但不能更改键。您可以删除项目,从而删除密钥,然后使用其他密钥重新插入,但为什么要首先这样做?我建议重新考虑你的逻辑。