我正在编写一个简单的程序,可以对数据执行删除,修改和其他操作。
不幸的是,我在修改二进制文件中的数据时遇到困难。
以下是updateRecord函数的代码。
当我尝试指出前一个记录时,VS2017会给我下一个错误:
"more then one operator '-' matches these operands"...
请帮忙,
谢谢!!!
#include <iostream>
#include <fstream>
#include <cstring>
#include <stdio.h>
using namespace std;
class Book
{
private:
int bookid;
char title[50];
float price;
public:
Book()
{
bookid = 0;
strcpy(title, "no title");
price = 0;
}
void getDate()
{
cout << "Enter book id, title and price.";
cin >> bookid;
cin.ignore();
cin.getline(title, 49);
cin >> price;
}
void showData()
{
cout << bookid << " " << title << " " << price << endl;
}
int storeDate();
void viewAllBooks();
void searchBook(char *);
void deleteBook(char *);
void updateBook(char *);
};
void Book::updateBook(char *t)
{
int pos;
fstream file;
file.open("file.dat", ios::ate | ios::in | ios::out | ios::binary);
file.seekg(0); // read data from the begining of file
file.read((char *)this, sizeof(*this));
while (!file.eof()) // it return 1 so i use not operator to break while loop
{
if (!strcmp(title, t))
{
getDate();
file.seekp(file.tellg() - sizeof(this));
file.write((char *)this, sizeof(*this));
}
file.read((char *)this, sizeof(*this));
}
file.close();
}
void Book::deleteBook(char *t)
{
ifstream fin;
ofstream fout;
fin.open("file.dat", ios::in | ios::binary);
if (!fin.is_open())
{
cout << "File not found" << endl;
}
else
{
fout.open("temp.dat", ios::out | ios::binary);
fin.read((char*)this, sizeof(*this)); //
while (!fin.eof())
{
if (strcmp(title, t))
{
fout.write((char *)this, sizeof(*this));
}
fin.read((char *)this, sizeof(*this));
}
fin.close();
fout.close();
remove("file.dat");
rename("temp.dat", "file.dat");
}
}
int Book::storeDate()
{
if (bookid == 0 && price == 0)
{
cout << "Book data in not initialized." << endl;
return (0);
}
else
{
// write data on file
ofstream fout;
fout.open("file.dat", ios::app | ios::binary);
fout.write((char*)this, sizeof(*this));
fout.close();
return (1);
}
}
void Book::searchBook(char *t)
{
int count = 0;
ifstream fin;
fin.open("file.dat", ios::in | ios::binary);
if (!fin.is_open())
{
cout << "File not found" << endl;
}
else
{
fin.read((char*)this, sizeof(*this));
while (!fin.eof())
{
if (!strcmp(t, title))
{
showData();
count++;
}
fin.read((char*)this, sizeof(*this));
}
if (count == 0)
{
cout << "No record Found." << endl;
}
fin.close();
}
}
void Book::viewAllBooks()
{
ifstream fin;
fin.open("file.dat", ios::in | ios::binary);
if (!fin.is_open())
{
cout << "File not found" << endl;
}
else
{
// type casting is using here as char
fin.read((char*)this, sizeof(*this));
while (!fin.eof())
{
showData();
fin.read((char*)this, sizeof(*this));
}
fin.close();
}
}
int main()
{
int choice;
char t[50];
Book b1;
cout << "1- Add Book" << endl;
cout << "2- View all Books" << endl;
cout << "3- Find a Book" << endl;
cout << "4- Delete a Book" << endl;
cout << "5- Update Book" << endl;
cout << "Enter choice: ";
cin >> choice;
switch (choice)
{
case 1:
b1.getDate();
b1.storeDate();
break;
case 2:
b1.viewAllBooks();
break;
case 3:
cout << "Enter Book title: ";
cin.ignore();
cin.getline(t, 49);
b1.searchBook(t);
break;
case 4:
cout << "Enter Book title: ";
cin.ignore();
cin.getline(t, 49);
b1.deleteBook(t);
break;
case 5:
cout << "Enter Book title: ";
cin.ignore();
cin.getline(t, 49);
b1.updateBook(t);
break;
default:
cout << "You entered invalid choice." << endl;
break;
}
system("PAUSE");
}
答案 0 :(得分:2)
G ++的完整错误消息为:
foo.cpp: In member function ‘void Book::updateBook(char*)’:
foo.cpp:57:46: warning: ISO C++ says that these are ambiguous, even though the worst conversion for the first is better than the worst conversion for the second:
file.seekp(file.tellg() - sizeof(this));
^
In file included from /usr/include/c++/5/iosfwd:40:0,
from /usr/include/c++/5/ios:38,
from /usr/include/c++/5/ostream:38,
from /usr/include/c++/5/iostream:39,
from foo.cpp:2:
/usr/include/c++/5/bits/postypes.h:192:7: note: candidate 1: std::fpos<_StateT> std::fpos<_StateT>::operator-(std::streamoff) const [with _StateT = __mbstate_t; std::streamoff = long int]
operator-(streamoff __off) const
^
foo.cpp:57:46: note: candidate 2: operator-(std::streamoff {aka long int}, long unsigned int) <built-in>
file.seekp(file.tellg() - sizeof(this));
^
因此,基本上,编译器无法在operator-()
提供的std::fpos
与long int
/ long unsigned int
提供的tellg()
之间做出决定。
我不太清楚你的代码想要完成什么 - 那里没有任何评论,当我试图从源头中找出你的意图时我的大脑会受伤 - 但是:
1)您可以将size_t
的结果转换为sizeof
,或将std::streamoff
的结果转换为*this
,以使错误消失(因为模糊性得到解决)
2) 不会覆盖BookCollection
。我不太确定你打算在那里做什么,但我很确定你没有做到(正确)。通过闭着眼睛看着它,我敢说应该有另一个类,可能是std::vector< Book >
,它拥有std::istream & operator>>( std::istream &, Book & )
,并且有一个std::ostream & operator<<( std::ostream &, Book const & )
和{{{{ 1}}实现您应该能够从/向文件读取/写入单个Book
数据而不会破坏某些内容。
// Warning, untested, on-the-fly
// In the declaration of class Book
// (You need to "friend" these functions so they
// may access Book private member variables.)
friend std::ostream & operator<<( std::ostream & ostr, Book const & book );
friend std::istream & operator>>( std::istream & istr, Book & book )
// Outside the declaration -- these are NOT
// member functions of class Book!
std::ostream & operator<<( std::ostream & ostr, Book const & book )
{
// Writing relevant data to stream -- this might
// be a file, std::cout, or even a socket...
ostr << book.bookid << "\n" << book.price << "\n" << book.title << "\n";
return ostr;
}
std::istream & operator>>( std::istream & istr, Book & book )
{
// Reading the relevant data. This needs to mirror
// what operator<<() does, above.
istr >> book.bookid;
istr >> book.price;
// Assuming you use `std::string` for book.title,
// which would be the sensible thing to do
std::getline( istr, book.title );
return istr;
}
// Somewhere else (e.g. in class BookCollection)
Book book;
std::fstream file;
// open file, positioning, ...
// Note that positioning is now done line-based
// (three lines to a book -- take care that no
// newlines are entered as part of the title!),
// not via some sizeof( *this ) hackmudgery.
// Reading a book entry...
file >> book;
// ...and writing it.
file << book;
答案 1 :(得分:1)
问题是sizeof(*this)
与operator-
重载完全不匹配,因此在选择正确的重载时存在歧义。要修复,只需自己选择一个过载:
file.seekp(file.tellg() - std::streamoff(sizeof(this)));