2013-01-07 57 views
1

我想使用随机访问文件管理为学校创建一个仓库程序。 我建立了一个叫做product(prodotto)的类,它有很多私有变量,我必须创建一个新记录。在随机访问文件问题中创建新记录

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

问题是,我每次运行该功能前的记录被删除。

在此版本之前,我使用了一般的fstream来完成这项工作,但情况更糟。 file.dat总是空的。

我用tellg和tellp检查了指针,它们都没问题。阅读部分似乎也没问题。我认为问题在于书面声明。

这是函数:

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 successfully\n"<<endl; 
outputLine(cout,prodotto); 
inOutProd.close(); 

} 
else 
{ 
    cerr<<"The product"<<codice<<"is already in our database"<<endl; 

} 

} 
+0

您尝试过'ios :: app'吗? –

+0

是的,结果是程序追加数据在文件的末尾,但以这种方式指针结构不起作用... – Garini

回答

0

你需要编写一个新的记录之前检查seekp调用的返回值。如果文件长度不足以包含记录N,seekp将返回一个错误代码,并且您必须将数据附加到该文件,以便它足够长以包含记录N.

+0

seekp似乎没问题。 tellkg重新运行-1(失败)。我怎么能抓住这个例外? 谢谢你的回答:) – Garini

+0

在你调用seekg之后检查fstream的状态位。如果失败位已设置,则表示文件中的请求位置无法到达 - 文件不足以包含所需的记录。 –