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

时间:2018-05-05 22:01:45

标签: c++ c++11 stl containers

我的填充容器地图有问题。我用运营商&gt;&gt;阅读了这些信息。但它在我的二级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 如果有人可以帮助我,我将非常感激。

这是我的运营商&lt;&lt;和&gt;&gt;在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;}

这是我的运营商&lt;&lt;和&gt;&gt;在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
}

这是带参数的构造函数:文件名和这些操作符&lt;&lt;,&gt;&gt;

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;

    }

最后是main()

#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;
}

2 个答案:

答案 0 :(得分:1)

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
}

答案 1 :(得分:0)

问题

问题可以归结为以下情况:

#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>>

我们有一个map包含pair

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

使<{p>}成为it->first

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

const CStock并导致报告错误。

这一切都有道理,因为map是按键排序的,所以如果你想随心所欲地更改密钥,map很快就会不连贯。

Documentation on std::map

解决方案

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