2016-02-01 77 views
-1

我試圖做一個登錄表單,我已經把一個選項來修改用戶的電子郵件ID,一旦他已登錄爲我寫了。下面的代碼。C++:無法修改某些記錄在一個文件

char newmail[50]; 
         cout<<"Enter New Email Id\n"; 
         cin>>newmail; 
         fstream f2; 
         f2.open("db.txt" , ios::out |ios::ate| ios::binary); 
         strcpy(u.email,newmail); 
         f2.seekp(pos,ios::beg); 
         cout<<f2.tellp()<<endl; 
         f2.write((char*)&u, sizeof(user)); 
         f2.close(); 
         cout<<"Details edited sucessfully\n"; 
       break; 

它的問題是:我登錄時選擇修改電子郵件ID選項。輸入新的。沒有錯誤,細節編輯成功。然後,當我去檢查用戶列表(寫了一個代碼爲好,完美的工作),所有用戶都無效,即它們的數據爲空,但空間仍然佔領,只有一個與所有數據記錄是電子郵件id爲modified.I想不通爲什麼當我已經使用f2.seekp(-sizeof(u),ios::cur);專門設置指針當前記錄的所有數據被廢止。 我已經交叉檢查了指針的位置,並且光​​標位於它的位置。 整個代碼是這樣的: -

#include<iostream> 
#include<fstream> 
#include<string.h> 
#include<stdlib.h> 

using namespace std; 

class user 
{public: 
    char username[50]; 
    char password[50]; 
    char email[50]; 


    int reg() 
    { 
     cout<<"REGISTRATION FORM\n"; 
     cout<<"Enter User name\n"; 
     cin>>username; 
     cout<<"Enter Email\n"; 
     cin>>email; 
     cout<<"Enter Password\n"; 
     cin>>password; 
    } 
    int putdata() 
    { 
     cout<<"Username "<<username<<"   "<<"Email ID "<<email<<endl; 
    } 

    char* retuser() 
    { 
     return username; 
    } 
    char* retpass() 
    { 

     return password; 
    } 
    char* retmail() 
    { 
     return email; 
    } 


}; 


int main() 
{int a=sizeof(user); 
    char ans; 
    int ch; 
    fstream f; 
    user u; 
    do 
    { 
     cout<<"MAIN MENU\n"; 
     cout<<"ENTER 1 FOR NEW REGISTRATION\n"; 
     cout<<"ENTER 2 TO LOGIN\n"; 
     cout<<"ENTER 3 FOR MEMBER LIST\n"; 
     cin>>ch; 

     if(ch==1) 
     { 
      u.reg(); 
      f.open("db.txt", ios::app|ios::out|ios::binary); 
      f.write((char*)&u, sizeof(user)); 
      f.close(); 
      cout<<"Registration successful\n"; 
     } 
     if(ch==2) 
     { 
      char uname[50]; 
      char pass[50]; 
      int flag=0; 
      cout<<"LOGIN\n"; 
      cout<<"Enter Username and Password\n"; 
      cin>>uname>>pass; 
      f.open("db.txt", ios::in | ios::binary); 
      f.read((char*)&u, sizeof(user)); 
      while(f) 
      { 
       if(strcmp(u.retuser(),uname)==0) 
       { 
        if(strcmp(u.retpass(),pass)==0) 
        { 
         flag=1; 
         cout<<"Login Successful\n"; 
         cout<<"USERNAME : -"<<u.retuser()<<endl; 
         cout<<"EMAIL ID : -"<<u.retmail()<<endl; 
         int pos; 
         pos=f.tellg(); 
         pos=pos-a; 
         int i; 
         cout<<"Press 1 to modify email id, 2 to exit\n"; 
         cin>>i; 
         if(i==1) 
         { 
          char newmail[50]; 
          cout<<"Enter New Email Id\n"; 
          cin>>newmail; 
          fstream f2; 
          f2.open("db.txt" , ios::out |ios::ate| ios::binary); 
          strcpy(u.email,newmail); 
          f2.seekp(pos,ios::beg); 
          cout<<f2.tellp()<<endl; 
          f2.write((char*)&u, sizeof(user)); 
          f2.close(); 
          cout<<"Details edited sucessfully\n"; 
          break; 
         } 
         else if(i==2) 
         { 
          exit(0); 
         } 
        } 
       } 
       f.read((char*)&u, sizeof(user)); 
      } 
      f.close(); 
       if(flag==0) 
      { 
       cout<<"Wrong username or password\n"; 
      } 
     } 
     if(ch==3) 
     { 
      cout<<"MEMBER LIST\n"; 

      f.open("db.txt", ios::in | ios::binary); 
      f.read((char*)&u, sizeof(user)); 
      while(f) 
      { 
       u.putdata(); 
       f.read((char*)&u, sizeof(u)); 
      } 
      f.close(); 

     } 

     cout<<"Enter y to go to main menu\n"; 
     cin>>ans; 
    }while(ans=='y' || ans=='Y'); 
} 
+0

是不是你的f.open()調用破壞了以前的文件內容?此外,代碼很脆弱:如果用戶輸入的電子郵件地址超過49個字符,緩衝區將溢出並導致未定義的行爲。 –

+0

@KlitosKyriacou請詳細說明f.open()調用的事情。另外我很清楚49個字符的限制。這只是一個學校項目,沒什麼大不了的! – Harshdeep

+0

試試這個:'的std ::法院<< -sizeof(用戶)<<的std :: ENDL;'。你可能會感到驚訝。 (是不是要更新的電子郵件程序很慢?我的是。) – molbdnilo

回答

0

爲了能夠修改文件時,你應該打開該文件(一次)的輸入和輸出正確的位置。即使您應該改善代碼並在許多其他部分添加一些用戶輸入檢查,我也只會向您顯示管理郵件地址更改的代碼部分。

if(ch==2) // I'd prefer a switch() here 
    { 
     char uname[50]; 
     char pass[50]; 
     int flag=0; 
     cout << "LOGIN\n"; 
     cout << "Enter Username and Password\n"; 
     cin >> uname >> pass; 
     fstream f("db.txt", ios::in | ios::out| ios::binary); 
     if (f.bad()) { 
      cout << "Error, unable to open users database file."; 
      exit(1); 
     } 
     // check the position BEFORE reading the user 
     int pos = f.tellg(); 
     while(f.read((char*)&u, sizeof(user))) { 
      if(strcmp(u.retuser(),uname) == 0 
        && strcmp(u.retpass(),pass) == 0) { 
       flag = 1; 
       cout << "Login Successful\n"; 
       cout << "USERNAME : -"<<u.retuser()<<endl; 
       cout << "EMAIL ID : -"<<u.retmail()<<endl; 
       int i; 
       cout << "Press 1 to modify email id, 2 to exit\n"; 
       cin >> i; 
       if(i == 1) { 
        char newmail[50]; 
        cout << "Enter New Email Id\n"; 
        cin >> newmail; 
        strcpy(u.email,newmail); 
        f.seekp(pos,ios::beg); 
        f.write((char*)&u, sizeof(user)); 
        cout << "Details edited sucessfully\n"; 
        break; 
       } else if (i == 2) { 
        exit(0); 
       } 
      } 
      pos=f.tellg(); 
     } 
     f.close(); 
     if (flag == 0) { 
      cout << "Wrong username or password\n"; 
     } 
    } 
相關問題