C ++, Как прочитать данные из файла и вставить в контейнер: Карта - PullRequest
0 голосов
/ 06 мая 2018

У меня проблема с заполнением карты контейнера информацией. Я читаю информацию с оператором >>, но она дает мне эти ошибки в моем втором классе CDealer. no operator ">>" matches these operands и binary">>": no operator found which takes a right-hand operand of type 'const CStock'(or these is no acceptable conversion) У меня есть три класса: CStock, CDealer с map<CStock, pair<unsigned, double>> Stock; и CShop с vector<CDealer*> Dealers; Я буду очень благодарен, если кто-то может мне помочь.

Это мои операторы << и >> в 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;

    }

И в конце 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 голосов
/ 06 мая 2018

Внедрение 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
}
0 голосов
/ 06 мая 2018

Задача

Проблема может быть уменьшена до следующего случая:

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

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

, что составляет it->first в

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

a const CStock и приводит к сообщенной ошибке.

Все это имеет смысл, потому что map заказывается ключом, поэтому, если бы вы могли изменить ключ в любое время на то, что вы хотели, map вскоре станет несогласованным.

Документация по std::map

Решение

Простого решения не существует. Ты не сможешь это сделать. Вы должны либо сделать элементы, а затем поместить их в map или использовать одну из функций семейства emplace, чтобы создать их непосредственно в map. Когда они введены в map, вы можете изменить значение, но не ключ. Вы можете удалить элемент и, следовательно, ключ, и заново вставить его с другим ключом, но почему вы делаете это в первую очередь? Я рекомендую переосмыслить вашу логику.

...