2011-10-20 31 views
0

這個項目是一個基本的ATM程序。我正在使用文件來存儲所有帳戶詳細信息。因此,每次運行.exe文件時,它都會從文件中讀取數據並將其插入AVL樹中。當我關閉程序時,AVL節點中的所有數據將被插回到文件中。C++中的文件I/O - 在寫回數據時遇到一些麻煩?

數據以此順序存儲在文件中(每個以換行符分隔)ID,密碼,名稱,添加,城市,引腳,平衡。 示例文件 -

12 
4576 
Vert 
No_999,GoLane 
Dallas 
89777 
50000 
16 
2342 
Nerd 
No_888,FoLane 
Chicago 
89999 
30000 

問題是我無法將數據寫回到文件中。有什麼建議嗎? P.S.請原諒我的在線類的方法,請... Program--

#include<iostream> 
#include<conio.h> 
#include<string.h> 
#include<fstream> 
using namespace std; 

fstream file("one2.txt",ios::in|ios::out);//Opening the file 'one2.txt' in global scope 

//AVL tree code starts here 

class avl 
{ 
    struct node //The structure node which is going to hold the data sets in the tree 
    { 
    int id,pwd; 
    char name[15],add[30],city[10]; 
    int pn; 
    double bal; 

    node *left, *right; 
    int height; 
    //node constructors 
    node(int i,int p,char nam[15], char a[30], char c[10],int pin,double b, node * l,node * r,int h) 
    { 
       id=i; 
       pwd=p; 
       strcpy(name,nam); 
       strcpy(add,a); 
       strcpy(city,c); 
       pn=pin; 
       bal=b; 
       left=l; 
       right=r; 
       height=h; 
    } 
    node() 
    { 
      left=right=NULL; 
      id=pwd=pn=0; 
      bal=0; 
      height=-1; 
    } 
}; 
node *root; 
node *nullnode; 

int Height(node *t)const //Func to return the height of a node 
{ 
    return((t==NULL)? -1:t->height); 
    } 

int max(int a,int b) 
{ 
    return(a>b)?a:b; 
    } 

    //Beginning of Insert() -- To create and insert data into the nodes 
    void insert(const int &x,int p, char nam[15], char a[30], char c[10],int pin,double b, node *&t) 
    { 
    if(t==NULL) 
     t = new node(x,p,nam,a,c,pin,b,NULL,NULL,-1); 
    else if(x<t->id) 
    { 
     insert(x,p,nam,a,c,pin,b,t->left); 
     if(Height(t->left) - Height(t->right)==2) 
     { 
        if(x<t->left->id) 
          single_rotate_with_left(t); 
        else 
         double_rotate_with_left(t); 
     } 
    } 

    else if(x>t->id) 
    { 
     insert(x,p,nam,a,c,pin,b,t->right); 
     if(Height(t->right)-Height(t->left)==2) 
     { 
       if(x>t->right->id) 
        single_rotate_with_right(t); 
       else 
        double_rotate_with_right(t); 
     } 
    } 
    else 
     t->height=max(Height(t->left),Height(t->right)+1); 
} 
//End of insert() 

//Func to print the node data. Just a sample to check if all the data 
// were inserted into the tree 
//Inorder traversal 
void print(node *&t) 
{ 
    if(t!=NULL) 
    { 
     print(t->left); 
     cout<<endl; 
     cout<<"ID "<<t->id<<" Name "<<t->name; 
     cout<<endl<<t->pwd<<endl<<t->add<<"\n"<<t->city; 
     cout<<"-"<<t->pn<<endl<<t->bal<<endl; 
     print(t->right); 
    } 
} 

    //Think there's gonna be no problem with the rotation and other AVL tree func codes. 
    //Beginning of AVL rotations 
    void single_rotate_with_left(node *&k2) 
    { 
    node *k1=k2->left; 
    k2->left=k1->right; 
    k1->right=k2; 
    k2->height=max(Height(k2->right),Height(k2->left))+1; 
    k1->height=max(Height(k1->left),(k2->height))+1; 
    k1=k2; 
    } 
    void single_rotate_with_right(node *&k2) 
    { 
    node *k1=k2->right; 
    k2->right=k1->left; 
    k1->left=k2; 
    k2->height=max(Height(k2->left),Height(k2->right))+1; 
    k1->height=max(Height(k1->right),(k2->height))+1; 
    k1=k2; 
    } 
    void double_rotate_with_left(node *&a) 
    { 
    single_rotate_with_right(a->left); 
    single_rotate_with_left(a); 
    } 
void double_rotate_with_right(node *&a) 
{ 
    single_rotate_with_left(a->right); 
    single_rotate_with_right(a); 
} 

//End of AVL rotations 

//Function to return the node. The 'id' variable to be searched is passed as a param 
node*& search(int x,node *&t) 
{ 

     if(t->id>x) 
      return search(x,t->left); 
     else if(t->id<x) 
      return search(x,t->right); 
     else if(t->id==x) 
      { 
       return t; 
      } 
     else 
        return nullnode; 
} 
//End of search. I'm using this in the loadnode() function. 

//This is where I try to write data back into the file. 
void update1(node *&t,int x) // x is the control variable 
{ 
    if(x==1) 
    //This block will be executed only once when the function is called for the 
    //first time. Used to seek to the beginning of the file 
    { 
      file.seekg(0,ios::beg); 
      x++; 
    } 
    if(t!=NULL)// Inorder traversal in the tree 
    { 

      update1(t->left,x); 

      //writing the data in the same order as it was stored. 
      file<<t->id<<endl; 
      file<<t->pwd<<endl; 
      file<<t->name<<endl; 
      file<<t->add<<endl; 
      file<<t->city<<endl; 
      file<<t->pn<<endl; 
      file<<t->bal<<endl; 

      update1(t->right,x); 
    }    
} 

public: 
    //Avl Constructor - This one is the one which is actually used. 
    avl(int x,int p,char nam[15], char a[30], char c[10],int pin,double b) 
    { 
      root= new node(x,p,nam,a,c,pin,b,NULL,NULL,-1); 
      nullnode=new node; 
    } 
    avl() 
    { 
      root->left=root->right=NULL; 
      root->height=-1; 
    } 

    //Call to the private insert function 
    void insert1(const int &x,int p,char nam[15], char a[30], char c[10],int pin,double b) 
    { 
      insert(x,p,nam,a,c,pin,b,root); 
    } 
    //Call to the private print() function 
    void display() 
    { 
      cout<<endl; 
      print(root); 
    } 



    //Function to write a new value for 'bal' variable to a node. 
    //I'm actually using this to update a node anconfirm whether the value of the updated node 
    //is reflected back at the node 
    void loadnode(int x) 
    { 
      node *&t=search(x,root); 
      cout<<"\nLoaded node...\n"; 
      cout<<t->id; 
      cout<<" "<<t->name; 
      t->bal=40000; 
      cout<<"\nUpdated Bal.."<<t->bal; 
    } 



    void update() 
    { 
      //file.seekp(0); 
      update1(root,1); 
    } 

};//End of AVL Class 



main() 
{ 

cout<<"The output..\n"; 
int i, p, pn; 
char n[15],a[30],c[10]; 
double b; 
int prev_id=0; 




file>>i>>p>>n>>a>>c>>pn>>b; 
prev_id=i; 
avl list(i,p,n,a,c,pn,b); 
while(file) 
    { 

     file>>i>>p>>n>>a>>c>>pn>>b; 
     if(prev_id!=i) 
     // I'm using this because i got a weird scenario in which the last record was repeated twice. 
     { 

     list.insert1(i,p,n,a,c,pn,b); 
     } 
     prev_id=i; 
    } 



    cout<<endl<<"The elements in AVL tree are...\n\n"; 
    list.display(); 
    list.loadnode(12);//12 is the id i used for one of my records. 
    //Calling to write back the data into the file. 
    list.update(); 

    file.close(); 
    getch(); 
    return 0; 
} 

//End of program 
+1

會發生什麼,或者更具體地說,你期望發生什麼? – Chad

+0

@chad當我試圖使用update()函數將數據寫回到文件中時,更改不會反映在文件中。 – Ganz7

+0

@ Ganz7嘗試檢查file.is_open()和file.good()返回true。在開始寫入文件之前,文件可能無法打開或發生錯誤。 – selalerer

回答

0

如果file.good()返回false,則以前對該文件的一些操作失敗(甚至可能是讀操作),並引發錯誤標誌之一文件對象。解決這個問題的一個難得的方法是使用file.clear(),它將清除錯誤標誌並允許下一個操作成功執行。解決這個問題的一個更好的方法是在每次操作後檢查是否有錯誤(file.good()爲false)並理解此操作失敗並修復它的原因。

+1

謝謝!有用!我試着檢查真正的問題是什麼,並解決它。 – Ganz7

+1

讀取操作將設置eof位,這就是寫入失敗的原因... – Nim

0

呼叫seekp()寫指針移動到流(fstream)的開頭。 seekg()移動get指針 - 在寫入時不會幫助...

+0

試過了。還是行不通。還是我在做別的事情? – Ganz7

+0

也清除()任何標誌。 – Nim

相關問題