dragonliu01
一般會員
發表:19 回覆:16 積分:7 註冊:2004-12-21
發送簡訊給我
|
這是我未完成的程式碼,由於要讀取變數count才有辦法做許多功能,不過每次重新開啟file ,count都會歸零,且搜尋功能也無法使用,
請問各位大大該如何改進或是有更好的方法做其他功能? #include
#include
#include
const int NAMESIZE=20;
using namespace std; class Student{
private :
int id;
int year;
char name[NAMESIZE];
string department;
double GPA;
public :
int getid();
int getyear();
char* getname();
string getdepartment();
double getgpa();
void setyear();
void setname();
void setdepartment();
void setgpa();
void setid();
void showdata();
Student editdata(int );
};
int Student::getid()
{return id;}
char* Student::getname()
{return name ;}
int Student::getyear()
{return year;}
string Student::getdepartment()
{return department;}
double Student::getgpa()
{return GPA;} void Student::setid()
{
cout<<"輸入學號\n";
cin>>id ;
} void Student::setyear()
{
cout<<"輸入年級\n" ;
cin>>year ;
} void Student::setname()
{
cout<<"輸入姓名\n" ;
cin>>name ;
} void Student::setdepartment()
{
cout<<"輸入系別\n" ;
cin>>department ;
} void Student::setgpa()
{
cout<<"輸入GPA值\n" ;
cin>>GPA ;
} void Student::showdata()
{
cout<<"姓名: "<>count; //讀取檔案中的count do{
cout<<"按'1'新增學生資料,按'2'搜尋學生資料,按'3'編輯學生資料,按'4'存檔並離開\n";
cin>>flag;
switch(flag)
{
case '1':
i=count; //將曾記過的數放入i
S[i].setid();
S[i].setname();
S[i].setyear();
S[i].setdepartment();
S[i].setgpa();
FileOutput<<"\n編號"<<'('<>flag;
switch(flag)
{
case 'a' :
S1.setid() ;
for(k=0;k<100;k )
{
if(S[k].getid()==S1.getid())
S[k].showdata();
}
break;
case 'b' :
S1.setname() ;
for(k=0;k<100;k )
{
if(S[k].getname()==S1.getname() )
S[k].showdata();
}
break;
case 'c' :
S1.setyear() ;
for(k=0;k<100;k )
{
if(S[k].getid()==S1.getyear() )
S[k].showdata();
}
break; case 'd' :
S1.setdepartment();
for(k=0;k<100;k )
{
if(S[k].getdepartment()==S1.getdepartment() )
S[k].showdata();
}
break; case 'e' :
S1.setgpa();
for(k=0;k<100;k )
{
if(S[k].getgpa()==S1.getgpa() )
S[k].showdata();
}
break;
}
//尚未完成 case 3 : case '4' :
FileOutput.close();
cout< 發表人 - dragonliu01 於 2005/06/08 23:49:15 發表人 - dragonliu01 於 2005/06/08 23:50:16
|
GeorgeKu
中階會員
發表:1 回覆:120 積分:74 註冊:2004-10-13
發送簡訊給我
|
dragonliu01, 1)你的程式中並未將count值寫入到檔案的開頭,所以你重新開啟檔案時,讀取不到實際的count值. 2)另外你必須考慮到將已存在檔案中的資料寫回到Student類別中,這樣才有辦法正確的使用搜尋功能.
|
dragonliu01
一般會員
發表:19 回覆:16 積分:7 註冊:2004-12-21
發送簡訊給我
|
引言:
dragonliu01, 1)你的程式中並未將count值寫入到檔案的開頭,所以你重新開啟檔案時,讀取不到實際的count值. FileInput>>count; //讀取檔案中的count
請問這步不算嗎?否則應該怎麼修改呢?抱歉我不太懂您所謂檔案開頭的意思。 2)另外你必須考慮到將已存在檔案中的資料寫回到Student類別中,這樣才有辦法正確的使用搜尋功能.
請問可以舉個簡單的例子嗎?謝謝....
|
GeorgeKu
中階會員
發表:1 回覆:120 積分:74 註冊:2004-10-13
發送簡訊給我
|
FileInput>>count; //讀取檔案中的count
上面這個是讀取count值,但是你程式中有把count值寫入檔案中嗎?
|
dragonliu01
一般會員
發表:19 回覆:16 積分:7 註冊:2004-12-21
發送簡訊給我
|
那改成如下對嗎?
case '1':
FileInput>>count;
i=count; //將曾記過的數放入i
S[i].setid();
S[i].setname();
S[i].setyear();
S[i].setdepartment();
S[i].setgpa();
FileOutput<<"\n編號"<<'('<
不過還是一樣從新計算....
|
GeorgeKu
中階會員
發表:1 回覆:120 積分:74 註冊:2004-10-13
發送簡訊給我
|
其實要達到你所要做的功能的話,對我而言我會選擇重寫,畢竟每個人的思考邏輯不同,所以我一開始提出的2個問題點,是針對你的作法上,那2點你必須考慮進去,才可以達到你要的目的.
開始沒有很仔細的看,你的code是有把count值寫進去,下面的i值
FileOutput<<"\n編號"<<'('<
但是你的問題是要如何把最後一筆資料的編號讀到count去. 另外針對把資料寫到類別中,我的作法如下
#include
#include
#include
using namespace std;
class Student
{
private:
char name[20];
public:
void setname(char *str)
{
strcpy(name,str);
}
void show()
{
cout<>temp;
S[count].setname(temp);
count ;
}
for(int i=0;i
test.txt內自己編一些名稱進去.
|
GeorgeKu
中階會員
發表:1 回覆:120 積分:74 註冊:2004-10-13
發送簡訊給我
|
如果不考慮檔案的可讀性,建議用2進位的方式儲存物件,以下紅色的部分是幫你修改的code,你可以試看看
#include
#include
#include
const int NAMESIZE=20;
using namespace std; class Student{
private :
int id;
int year;
char name[NAMESIZE];
char department[NAMESIZE];
double GPA;
public :
int getid();
int getyear();
char* getname();
char* getdepartment();
double getgpa();
void setyear();
void setname();
void setdepartment();
void setgpa();
void setid();
void showdata();
Student editdata(int );
};
int Student::getid()
{return id;}
char* Student::getname()
{return name ;}
int Student::getyear()
{return year;}
char* Student::getdepartment()
{return department;}
double Student::getgpa()
{return GPA;} void Student::setid()
{
cout<<"輸入學號\n";
cin>>id ;
} void Student::setyear()
{
cout<<"輸入年級\n" ;
cin>>year ;
} void Student::setname()
{
cout<<"輸入姓名\n" ;
cin>>name ;
} void Student::setdepartment()
{
cout<<"輸入系別\n" ;
cin>>department ;
} void Student::setgpa()
{
cout<<"輸入GPA值\n" ;
cin>>GPA ;
} void Student::showdata()
{
cout<<"姓名: "<>flag;
switch(flag)
{
case '1':
i=count; //將曾記過的數放入i
S[i].setid();
S[i].setname();
S[i].setyear();
S[i].setdepartment();
S[i].setgpa();
FileOutput.write((char*)&S[i],sizeof(Student));
i ;
count=i;//再將i 1值放回count
break ; case '2' :
cout<<"輸入要搜尋的資料 :\n "
<<"(A)ID (B)姓名 (C)年級 (D)系別 (E)GPA \n";
cin>>flag;
switch(flag)
{
case 'a' :
S1.setid() ;
for(k=0;k<100;k )
{
if(S[k].getid()==S1.getid())
S[k].showdata();
}
break;
case 'b' :
S1.setname() ;
for(k=0;k<100;k )
{
if(S[k].getname()==S1.getname() )
S[k].showdata();
}
break;
case 'c' :
S1.setyear() ;
for(k=0;k<100;k )
{
if(S[k].getid()==S1.getyear() )
S[k].showdata();
}
break; case 'd' :
S1.setdepartment();
for(k=0;k<100;k )
{
if(S[k].getdepartment()==S1.getdepartment() )
S[k].showdata();
}
break; case 'e' :
S1.setgpa();
for(k=0;k<100;k )
{
if(S[k].getgpa()==S1.getgpa() )
S[k].showdata();
}
break;
}
//尚未完成 case 3 : case '4' :
FileOutput.close();
cout<
|
dragonliu01
一般會員
發表:19 回覆:16 積分:7 註冊:2004-12-21
發送簡訊給我
|
請問可以解釋ㄧ下這句的語法嗎?
while(FileInput.read((char*)&S[count],sizeof(Student)))
{
count++;
}
手邊C++的書都沒說到binary file方面...
只有教過像這樣的語法..
os.write( reinterpret_cast(buff),MAX*sizeof(int) ); 發表人 - dragonliu01 於 2005/06/11 17:13:11 發表人 - dragonliu01 於 2005/06/11 17:13:41
|
GeorgeKu
中階會員
發表:1 回覆:120 積分:74 註冊:2004-10-13
發送簡訊給我
|
你書中介紹的語法也是等同我所用的語法,reinterpret_cast是C++中轉型的方式,我用的是C轉型的方式.如果把我所用的方式作成像你書中介紹的方式,語法會變成如下:
while(FileInput.read(reinterpret_cast(&S[count]),sizeof(Student)))
{
count ;
}
read or write的第一個參數原型是const char*,因為程式中要傳入的參數是Student物件,所以必須將物件指標轉型為char指標型態.這樣在編譯時才不會出現錯誤訊息.
|
GeorgeKu
中階會員
發表:1 回覆:120 積分:74 註冊:2004-10-13
發送簡訊給我
|
另外在你搜尋功能裡面,char型態的字串不能直接用==去比對,所以部分的code修改如下:
case 'b' :
S1.setname() ;
for(k=0;k<100;k )
{
if(strcmp(S[k].getname(),S1.getname())==0 )
S[k].showdata();
}
break;
case 'c' :
S1.setyear() ;
for(k=0;k<100;k )
{
if(S[k].getyear()==S1.getyear() )
S[k].showdata();
}
break; case 'd' :
S1.setdepartment();
for(k=0;k<100;k )
{
if(strcmp(S[k].getdepartment(),S1.getdepartment())==0 )
S[k].showdata();
}
break;
|
dragonliu01
一般會員
發表:19 回覆:16 積分:7 註冊:2004-12-21
發送簡訊給我
|
感謝大哥相救,以下是我修改過的程式碼,有些部份是因為(如string department),
不過還是老問題,資料寫的進去,讀不出...
#include
#include
#include
const int NAMESIZE=20;
using namespace std; class Student{
private :
int id;
int year;
char name[NAMESIZE];
string department;
double GPA;
public :
int getid();
int getyear();
char* getname();
string getdepartment();
double getgpa();
void setyear();
void setname();
void setdepartment();
void setgpa();
void setid();
void showdata();
void editdata();
};
/******************************************************************************/
int Student::getid() //這裡為set和get的函式
{return id;}
char* Student::getname()
{return name ;}
int Student::getyear()
{return year;}
string Student::getdepartment()
{return department;}
double Student::getgpa()
{return GPA;} void Student::setid()
{
cout<<"輸入學號\n";
cin>>id ;
} void Student::setyear()
{
cout<<"輸入年級\n" ;
cin>>year ;
} void Student::setname()
{
cout<<"輸入姓名\n" ;
cin>>name ;
} void Student::setdepartment()
{
cout<<"輸入系別\n" ;
cin>>department ;
} void Student::setgpa()
{
cout<<"輸入GPA值\n" ;
cin>>GPA ;
}
/******************************************************************************/
void Student::showdata()
{
cout<<"姓名: "<>flag;
switch(flag)
{
case 'a' :
s.setid();
break;
case 'b' :
s.setname() ;
break;
case 'c' :
s.setyear() ;
break; case 'd' :
s.setdepartment();
break; case 'e' :
s.setgpa();
break;
} } /******************************************************************************/
int main()
{
int i,j=1,k;
char flag;
Student S[100],S1;
string strcompare,temp;
char* FileNameIn= "student.txt"; //讀取這個file
char* FileNameOut= "Sstudent.txt";//寫入這個file ifstream FileInput(FileNameIn);
ofstream FileOutput(FileNameOut, ios::app);//以增加的方式寫入 do{
cout<<"按'1'新增學生資料,按'2'搜尋或編輯學生資料,按'3'存檔並離開\n";
cin>>flag;
switch(flag)
{
case '1':
S[i].setid();
S[i].setname();
S[i].setyear();
S[i].setdepartment();
S[i].setgpa();
FileOutput<<"\n姓名: "<>flag;
switch(flag)
{
case 'a' :
S1.setid() ;
for(k=0;k<100;k ) //比對學生id
{
if(S[k].getid()==S1.getid()) //用迴圈逐個比對
{
S[k].showdata();
break;
}
}
cout<<"修改請按'E'"<>flag;
if(flag=='e')
S[k].editdata(); //借用到S[k]可以順便修改
break;
case 'b' :
S1.setname() ;
for(k=0;k<100;k )
{
if(strcmp(S[k].getname(),S1.getname())==0 )//char array用strcmp比對
{
S[k].showdata();
break;
}
}
cout<<"修改請按'E'"<>flag;
if(flag=='e')
S[k].editdata();
break; case 'c' :
S1.setyear() ;
for(k=0;k<100;k )
{
{
S[k].showdata();
break;
}
}
cout<<"修改請按'E'"<>flag;
if(flag=='e')
S[k].editdata();
break;
case 'd' :
S1.setdepartment();
strcompare=S1.getdepartment();
for(k=0;k<100;k )
{
temp=S[k].getdepartment();
if(strcompare.compare(0,'\0',temp,0,'\0' ) )//由於是string 類別的物件,所以用string.compare()
{ //做比較
S[k].showdata();
break;
}
}
cout<<"修改請按'E'"<>flag;
if(flag=='e')
S[k].editdata();
break; case 'e' :
S1.setgpa();
for(k=0;k<100;k )
{
if(S[k].getgpa()==S1.getgpa()==0 )
{
S[k].showdata();
break;
}
}
cout<<"修改請按'E'"<>flag;
if(flag=='e')
S[k].editdata();
break;
} case '3' :
FileOutput.close();
cout<
|
GeorgeKu
中階會員
發表:1 回覆:120 積分:74 註冊:2004-10-13
發送簡訊給我
|
QQ 不知如何是好,你有注意到本身我已經把string物件改為char了嗎?這就是為了避免掉會存取錯誤的string物件,另外你寫的新CODE的部分,FileNameIn跟FileNameOut給的檔名不一樣,這也會造成問題.
我的code有測試過才貼上來的,所以應該不會有問題,或許你沒把原先的student_data.txt檔砍掉,所以程式引用了錯誤的檔案資料.
另外一個觀念問題,string物件可以直接用==去比較,所以不用像你所寫的那麼麻煩.
|
digitraveler
初階會員
發表:89 回覆:91 積分:46 註冊:2005-06-01
發送簡訊給我
|
就讀取變數"功能"而言,
INI 檔不是比 TXT 檔方便許多 ??
若真要讀取 TXT 檔變數 , 也可用 TStringList 物件的 Value 屬性...
不知為何要寫那麼一大堆 .... 如下 若 1.TXT 內容為
A=123
B=456 則
TStringList *MyList;
MyList = new TStringList;
MyList->LoadFromFile("1.txt");
ShowMessage(MyList->Values["A"]) ; //會秀出 "123"
ShowMessage(MyList->Values["B"]) ; //會秀出 "456" //還可將變數回存
MyList->Values["A"]="789";
MyList->SaveToFile("1.txt"); 1.TXT 內容即變為
A=789
B=456 你跟本不用管變數 A 是放在文字檔中的第幾行
|