Проблема C ++ для записи векторных данных в файл - PullRequest
0 голосов
/ 09 сентября 2011

Я хочу записать содержимое вектора v в файл.Проблема в том, что не текст, а адрес будет помещен в текстовый файл.

Когда я пишу * pos вместо & pos, я получаю ошибку: ошибка C2679: двоичный файл '<<': не найден оператор, который принимает правый операнд типа 'entry' </em>

Как это работает правильно?

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <limits>

/*
Data.txt 

John
6543
23

Max
342
2

A Team
5645
23
*/

struct entry
{
    // passengers data
    std::string name;
    int weight; // kg
    std::string group_code; 
};

void reservations(std::vector<entry> v)
{
    std::ofstream outfile;
    outfile.clear();
    outfile.open("reservations.txt");
    // print data in vector
    std::vector<entry>::iterator pos;
        for (pos = v.begin(); pos!= v.end();++pos)
        {
            outfile << &pos << std::endl;
            std::cout << &pos << std::endl;
        }
    outfile.close();
}

entry read_passenger(std::ifstream &stream_in)
{
    entry passenger;
    if (stream_in)
    {
        std::getline(stream_in, passenger.name); 
        stream_in >> passenger.weight;
        stream_in.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
        std::getline(stream_in, passenger.group_code);
        stream_in.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
        return passenger;
    }

    return passenger; 
}

int main(void)
{
    std::ifstream stream_in("data.txt"); 
    std::vector<entry> v; // contains the reservations
    std::vector<entry> a; // contains the cancellations
    const int limit_total_weight = 10000;   // kg
    int total_weight = 0;                   // kg
    entry current;
    while (stream_in)
    {
        current = read_passenger(stream_in);
        if (total_weight + current.weight >= limit_total_weight)
        {
            // push data (cancellations) to vector
            a.push_back(current);
        }
        else
        {
            total_weight = total_weight + current.weight;
            // push data (reservations) to vector
            v.push_back(current);
        }
    }
    reservations(v); // write reservations to file
    std::cout << "Rest " << limit_total_weight - total_weight << "kg" <<std::endl;
    return 0;
}

Ответы [ 6 ]

4 голосов
/ 09 сентября 2011

Вы должны перегрузить operator << для entry:

std::ostream& operator << (std::ostream& o, const entry& e) 
{
   return o << e.name 
     << " " << e.weight 
     << " " << e.gruop_code;
}

Теперь вы можете написать:

outfile << *pos << std::endl;
std::cout << *pos << std::endl;
0 голосов
/ 09 сентября 2011

Причина, по которой ваши выходные данные выглядят как адреса с настоящим кодом, заключается в том, что вы выводите адрес итератора.

Причина, по которой вы получаете ошибку «не найден оператор, который принимает правый оператор типа« запись »», заключается в том, что нет оператора <<, который принимает entry в качестве правого операнда,Вы можете легко определить одно:

std::ostream&
operator<<( std::ostream& dest, entry const& obj )
{
    dest << obj.name;
    return dest;
}

Но это немного специализировано;в других контекстах вы можете вывести другие поля entry.Классически, фактически, operator<< для entry будет выводить все соответствующие поля.Альтернативным решением было бы определить функциональный объект преобразователя и использовать его:

struct EntryToName
{
    std::string operator()( entry const& obj ) const
    {
        return obj.name;
    }
};

Затем в reservations:

std::transform( 
    v.begin(), v.end(),
    std::ostream_iterator<std::string>( outfile, "\n" ),
    EntryToName() );

И кстати, обычно считается предпочтительным передавать векторыпо константной ссылке, а не по значению.

0 голосов
/ 09 сентября 2011

Попробуйте что-то вроде:

std::ostream& operator<<(std::ostream& os,const entry& toPrint)
{
  os << "name :" << toPrint.name << '\n';
  os << "weight :" << toPrint.weight << "(kg) \n";
  os << "group_code :" << toPrint.group_code << '\n';
  return os;
}

также вы можете изменить подпись функции бронирования на

void reservations(const std::vector<entry>& v)
0 голосов
/ 09 сентября 2011

Поскольку entry является простой структурой, и вы не определили никакой метод operator<< для записи его содержимого в выходной поток, компилятор жалуется, когда вы пытаетесь записать *pos напрямую.

Либо вам нужно определить подходящий operator<< метод, либо выписать членов структуры один за другим, например

        outfile << pos->name << std::endl;
        outfile << pos->weight << std::endl;
        outfile << pos->group_code << std::endl;
0 голосов
/ 09 сентября 2011

Вам придется либо выполнить outfile << pos->name << " " << pos->weight << /* etc */, либо реализовать оператор вывода, operator<<.

Это будет выглядеть примерно так:

   std::ostream& operator<<(std::ostream& os, const entry&) {
        return os << entry.name << " " << entry.weight << " " << entry.group_code;
   }

Форматировать при необходимости.

0 голосов
/ 09 сентября 2011

Сначала вы писали указатель, а затем не сказали С ++, как entry должно быть представлено в тексте.

Создайте для него перегрузку operator<<.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...