我已经问了两个与这个项目有关的问题,我得出了这个结论。将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
这是我现在唯一的错误。我看到你的代码好多了。我的新编译器错误超长。我已经显示了错误指向的位置。你能帮我最后一次吗?
答案 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>
。