简体   繁体   English

将向量数据写入文件的C ++问题

[英]C++ problem to write vector data to file

I want to write the content of the vector v to a file. 我想将向量v的内容写入文件。 Problem is that not the content but the address will be placed inside the textfile. 问题在于,不是内容而是地址将放置在文本文件中。

When I write *pos inplace of &pos I get the error: error C2679: binary '<<' : no operator found which takes a right-hand operand of type 'entry' 当我用* pos 代替 &pos时,出现错误: 错误C2679:二进制'<<':未找到采用'entry'类型的右操作数的运算符

How does it work correct? 如何正确运作?

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

You should overload operator << for entry : 您应该重载operator <<以便entry

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

Now you can write: 现在您可以编写:

outfile << *pos << std::endl;
std::cout << *pos << std::endl;

First you were writing a pointer, and then you didn't tell C++ how an entry should be represented in text. 首先,您正在编写一个指针,然后您没有告诉C ++ entry应如何用文本表示。

Create an operator<< overload for it. 创建一个operator<<重载。

You will either have to do outfile << pos->name << " " << pos->weight << /* etc */ , or implement a output operator, operator<< . 您将必须执行outfile << pos->name << " " << pos->weight << /* etc */ ,或实现输出运算operator<<

It will look something like 它看起来像

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

Format as needed. 根据需要设置格式。

Since entry is a plain struct, and you haven't defined any operator<< method to write its contents to an output stream, the compiler complains when you try to write out *pos directly. 由于entry是普通结构,并且您尚未定义任何operator<<方法将其内容写入输出流,因此,当您尝试直接写出*pos时,编译器会抱怨。

Either you need to define a suitable operator<< method, or write out the members of the struct one by one, like 您需要定义一个合适的operator<<方法,或者逐个写出struct的成员,例如

        outfile << pos->name << std::endl;
        outfile << pos->weight << std::endl;
        outfile << pos->group_code << std::endl;

Try something like: 尝试类似:

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

also you may want change the signature of the reservation function to 您也可能希望将保留功能的签名更改为

void reservations(const std::vector<entry>& v)

The reason your output looks like addresses with the present code is because you're outputting the address of the iterator. 您的输出看起来像带有当前代码的地址的原因是因为您正在输出迭代器的地址。

The reason why you get the error "no operator found which takes a right-hand operator of type 'entry'" is because there is no << operator which takes an entry as its right hand operand. 之所以出现错误“没有找到采用'entry'类型的右手运算符的错误”的原因是因为没有<<entry作为其右手操作数的运算符。 You can easily define one: 您可以轻松定义一个:

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

But this is a bit specialized; 但这有点专业。 in other contexts, you might want to output other fields of entry . 在其他情况下,您可能希望输出其他entry字段。 Classically, in fact, an operator<< for entry would output all relevant fields. 实际上,经典而言,实际上,用于entryoperator<<将输出所有相关字段。 An alternative solution would be to define a transformer functional object, and use it: 一种替代解决方案是定义一个变压器功能对象并使用它:

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

Then in reservations : 然后在reservations

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

And BTW, it's generally considered preferrable to pass vectors by const reference, rather than by value. 顺便说一句,通常认为最好通过const引用而不是通过值传递向量。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM