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

C++ problem to write vector data to file

本文关键字:文件 C++ 问题 数据      更新时间:2023-10-16

我想将向量v的内容写入一个文件。问题是,不是内容而是地址将被放置在文本文件中。

当我写*pos代替&pos我得到错误:错误C2679:二进制'<lt;':找不到接受类型为"entry"的右侧操作数的运算符

它是如何正确工作的?

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

您应该为entry:重载operator <<

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;

首先编写了一个指针,然后没有告诉C++应该如何在文本中表示entry

为其创建一个operator<<重载。

由于entry是一个普通结构,并且您还没有定义任何operator<<方法来将其内容写入输出流,因此当您尝试直接写出*pos时,编译器会抱怨。

要么需要定义一个合适的operator<<方法,要么像一样逐个写出结构的成员

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

尝试以下操作:

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)

您的输出看起来像当前代码中的地址的原因是因为您正在输出迭代器的地址。

出现错误"未找到需要类型为"entry"的右侧运算符是因为没有<<将CCD_ 10作为其右手操作数的运算符。你可以很容易定义一个:

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

但这有点专业化;在其他情况下,您可能希望输出CCD_ 11的其它字段。事实上,经典的operator<<对于CCD_ 13将输出所有相关字段。替代解决方案将定义一个transformer函数对象,并使用它:

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() );

顺便说一句,通常认为通过const传递向量更可取引用,而不是按值。

您必须执行outfile << pos->name << " " << pos->weight << /* etc */,或者实现一个输出运算符operator<<

它看起来有点像

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

根据需要设置格式。