在将多个结构的读/写大小编译到文件时编译错误

时间:2009-04-02 03:55:08

标签: c++ serialization struct compiler-errors

我已经问了两个与这个项目有关的问题,我得出了这个结论。将Struct的大小写入文件,然后将其读回是执行此操作的最佳方法。

我正在创建一个家庭作业的程序,这将允许我维护库存。我需要读取/写入相同类型的多个结构到文件。

问题是......这真的很复杂,我在整个过程中遇到麻烦。我已经看过很多例子,我试图把它们放在一起。我收到了编译错误......我对如何修复它们一无所知。如果你可以帮助我,我会非常感激......谢谢。我现在迷路了...

****最后编辑最后编辑#3 *************

我的代码:

// Project 5.cpp : main project file.

#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <algorithm>

using namespace System;
using namespace std;
#pragma hdrstop

int checkCommand (string line);

template<typename Template>
void readFromFile(Template&);

template<typename Template>
void writeToFile(Template&);

template<typename T>
void writeVector(ofstream &out, const vector<T> &vec);

template<typename Template>
void readVector(ifstream& in, vector<Template>& vec);

struct InventoryItem {
    string Item;
    string Description;
    int Quantity;
    int wholesaleCost;
    int retailCost;
    int dateAdded;
} ;


int main(void)
{
    cout << "Welcome to the Inventory Manager extreme! [Version 1.0]" << endl;

    vector<InventoryItem> structList;

    ofstream out("data.dat");

    writeVector( out, structList );

    while (1)
    {

        string line = "";

        cout << endl;
        cout << "Commands: " << endl;
        cout << "1: Add a new record " << endl;
        cout << "2: Display a record " << endl;
        cout << "3: Edit a current record " << endl;
        cout << "4: Exit the program " << endl;
        cout << endl;
        cout << "Enter a command 1-4: ";

        getline(cin , line);


        int rValue = checkCommand(line);
        if (rValue == 1)
        {
            cout << "You've entered a invalid command! Try Again." << endl;
        } else if (rValue == 2){ 
            cout << "Error calling command!" << endl;
        } else if (!rValue) {
            break;
        }
    }


    system("pause");

    return 0;
}

int checkCommand (string line)
{
    int intReturn = atoi(line.c_str());
    int status = 3;

    switch (intReturn)
    {
        case 1:
            break;
        case 2:
            break;
        case 3:
            break;
        case 4:
            status = 0;
            break;
        default:
            status = 1;
            break;
    }
    return status;
}

template <typename Template>
void readFromFile(Template& t)
{
    ifstream in("data.dat");
    readVector(in, t); Need to figure out how to pass the vector structList via a Template
    in.close();
}

template <typename Template>
void writeToFile(Template& t)
{
    ofstream out("data.dat");
    readVector(out, t); Need to figure out how to pass the vector structList via a Template
    out.close();
}

template<typename T>
void writeVector(ofstream &out, const vector<T> &vec)
{
    out << vec.size();

    for(vector<T>::const_iterator i = vec.begin(); i != vec.end(); ++i)
    {
        out << *i; // SUPER long compile error
    }
}

template<typename T>
vector<T> readVector(ifstream &in)
{
    size_t size;
    in >> size;

    vector<T> vec;
    vec.reserve(size);

    for(int i = 0; i < size; ++i)
    {
        T tmp;
        in >> tmp;
        vec.push_back(tmp);
    }

    return vec;
}

我的编译错误:

1>.\Project 5.cpp(128) : error C2679: binary '<<' : no operator found which takes a right-hand operand of type 'const InventoryItem' (or there is no acceptable conversion)
1>        C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\ostream(653): could be 'std::basic_ostream<_Elem,_Traits> &std::operator <<<char,std::char_traits<char>>(std::basic_ostream<_Elem,_Traits> &,const char *)'
1>        with

这是我现在唯一的错误。我看到你的代码好多了。我的新编译器错误超长。我已经显示了错误指向的位置。你能帮我最后一次吗?

3 个答案:

答案 0 :(得分:2)

您的读写功能有问题。特别是,你应该做这样的事情:

template<typename T>
void write(ofstream &out, const T &t)
{
    out << T;
}

OLD: bind1st要求您包含functional才能使其发挥作用:

#include <functional>

不是处理所有这些函数等,而是依靠迭代器更好:

template<typename T>
void writeVector(ofstream &out, const vector<T> &vec)
{
    out << vec.size();

    for(vector<T>::const_iterator i = vec.begin(); i != vec.end(); ++i)
    {
        out << *i;
    }
}

template<typename T>
vector<T> readVector(ifstream &in)
{
    size_t size;
    in >> size;

    vector<T> vec;
    vec.reserve(size);

    for(int i = 0; i < size; ++i)
    {
        T tmp;
        in >> tmp;
        vec.push_back(tmp);
    }

    return vec;
}

您还希望函数能够读取和写入InventoryItem,可能是:

ostream &operator<<(ostream &out, const InventoryItem &i)
{
    out << i.Item << i.Description;  // FIXME Read/write strings properly.
    out << i.Quantity;
    out << i.wholesaleCost << i.retailCost;
    out << i.dateAdded;
}

istream &operator>>(istream &out, InventoryItem &i)
{
    // Keep in same order as operator<<(ostream &, const InventoryItem &)!
    in >> i.Item >> i.Description;  // FIXME Read/write strings properly.
    in >> i.Quantity;
    in >> i.wholesaleCost >> i.retailCost;
    in >> i.dateAdded;
}

答案 1 :(得分:2)

答案 2 :(得分:1)

编辑:尝试清除FUD:

bind1st是STL的functional标题的一部分。在升级出现之前存在STL。它在C ++ 0x中被弃用,支持更通用的版本,即bind(又名boost::bind)。有关详细信息,请参见附录D.8粘合剂。

现在真正的问题(多次编辑可能会使这看起来很傻,但为了后人的缘故,我会保留这个):

 write<long>(out, structList.size());

这是违规行。这需要long作为第二个参数,而vector的{​​{1}}类型为size()size_t

更新有错字:使用unsigned int而不是size_t

size_T

下一部分:

write<size_t>(out, structList.size());

这应该是 for_each(structList.begin(), structList.end(), bind1st(write<InventoryItem>, out)); 或其他类型。另外,请structList添加functional。在顶部添加:

bind1st

模板#include <functional> 需要一个仿函数。没有其他一些黑客攻击,传递普通函数指针是不可能的。您可以使用bind1st作为替代方案。或者:

boost::bind

现在其他的挑剔:

什么是:

for(InventoryItem::iterator i = structList.begin(), f = structList.end();
         i != f; ++i)
    write<InventoryItem>(out, *i);

你确定你在这里使用的是什么吗?如果你想要STL字符串,你需要包括:

#include <String>
...
using namespace System;

不是标准签名。使用以下任何一个:

#include <string>

void main(void)

int main(void)

使用预定义的插入/提取运算符,I / O通常会更容易。你可以(并且真的应该)使用:

int main(int argc, char *argv[]);

和类似的

istream is(...);
is >> data;

另请注意,您的ostream os(...); os << data; readFromFile功能需要修复才能使用writeToFile而不是vector<InventoryItem>