在随机访问文件中创建新记录问题

Creating new record in a random access file issue

本文关键字:创建 新记录 问题 文件 随机 访问      更新时间:2023-10-16

我想使用随机存取文件管理为学校创建一个仓库程序。我构建了一个名为product(prodotto)的类,其中包含许多私有变量,我必须创建一个新记录。

函数用seekg指针检查产品是否已经存在,并读取文件。如果没有的话,你可以在那个空间中写入文件。关键是产品代码(codice)。

问题是每次运行该函数时,前一条记录都会被擦除。

在此版本之前,我使用通用的fstream来完成工作,但它更差。file.dat总是空的

我用tellg和tellp检查了指针,它们是ok的。阅读部分也不错。我认为问题出在写作语句上。

功能如下:

void aggiungiProd()
{
    int code;
    string name,section, description;
    int quantity;
    double price;

    cout<<"n(insert 0 to come back)"<<endl;
    //exit condiction
    cout<<"Insert product code:";
cin>>code;

if( cin.good()==0)
{ code=0;
    cout<<"invalid code. Please reinsert:"<<endl;
cin>>code;
} //also this part is not working but is less important

if(codice==0) return;//exit condition

ifstream readFile("prod.dat",ios::in);
if(!readFile){
        cerr<<"Error during the reading";
 exit(1);
    }
int var;
var=code-1;
//use a pointer to indicate the location to read
readFile.seekg(var * (sizeof(Prodotto)),ios::beg );

//reading the product record
Prodotto prodotto;
readFile.read(reinterpret_cast< char*> (&prodotto),sizeof(Prodotto));

readFile.close();
if(prodotto.getCod()==0)
{

//THIS PART IS ONLY ABOUT VARIABLES TO SET--> SKIP
cout<<"Inserisci il nome del prodotto (max 30 caratteri): ";
cin.ignore();
getline(cin,name);
if(name=="0") return;//condizione uscita
cout<<"Inserisci quantità da aggiungere: ";
cin>>quantita;
if(quantita==0) return;
cout<<"Inserisci il prezzo del prodotto: " ;
cin>>prezzo;
if(prezzo==0) return;
cout<<"Inserisci sezione di appartenenza del prodotto(max 15 caratteri): " ;
cin.ignore();
getline(cin,sezione);
if(sezione=="0") return;
cout<<"Aggiungi una descrizione del prodotto (max 500 caratteri):";
cin.ignore();
getline(cin,descrizione);
if(descrizione=="0") return;
//END OF THE VARIABLES INSERTION

//NOW PUT THE VARIABLES IN THE PRODUCT prodotto
    prodotto.setCod(codice);
    prodotto.setNome(nome);
    prodotto.setQta(quantita);
    prodotto.setPrz(prezzo);
    prodotto.setSez(sezione);
    prodotto.setDes(descrizione);
//open the file as output
ofstream inOutProd("prod.dat", ios::out );
if(!inOutProd){
        cerr<<"Error in the file creation";
 exit(1);
    }
//pointer for the location of the new record
inOutProd.seekp(var * (sizeof(Prodotto)));

//write the record prodotto
inOutProd.write(reinterpret_cast<const char*>(&prodotto),sizeof(Prodotto));
//i believe the problem is in the statement over this line. I tried also to add ios::app
// in the ofstream line but it only append the new record at the end of file.

cout<<"the following product has been saved successfullyn"<<endl;
outputLine(cout,prodotto);
inOutProd.close();
}
else
{
    cerr<<"The product"<<codice<<"is already in our database"<<endl;
}
}

您需要在写入新记录之前检查seekp调用的返回值。如果文件的长度不足以包含记录N, seekp将返回一个错误代码,您必须向文件追加数据,使其长度足以包含记录N。