全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:1458
推到 Plurk!
推到 Facebook!

已經最簡化,但存檔值會異常

答題得分者是:Stallion
kenneth_c
一般會員


發表:5
回覆:8
積分:2
註冊:2007-08-03

發送簡訊給我
#1 引用回覆 回覆 發表時間:2007-09-02 16:49:47 IP:61.61.xxx.xxx 訂閱
各位前輩:小弟寫了一個存檔的,但不知是格式有錯,還是bcb哪裡真的有點問題,只要以下的程式中,任意一個DATA 輸入處,設值3500或3400後按SAVE儲值,再重開程式,其就會錯亂,而輸入其他值就正常,小弟有試過宣告變數改用 double 方式,其值也會正常,請各位前輩幫幫看一下,謝謝。 
<textarea class="cpp" rows="10" cols="60" name="code">#include #pragma hdrstop #include #include #include "Unit1.h" #include "Io.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; struct M_setting_struct { int DATA1,DATA2,DATA3,DATA4,DATA5,DATA6; }; M_setting_struct M_setting; FILE *F_mptr; //--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { } //--------------------------------------------------------------------------- void __fastcall TForm1::FormCreate(TObject *Sender) { char *f_n1=".\\set1.dat"; F_mptr=fopen(f_n1,"r "); fseek(F_mptr,0,0); fread(&M_setting,sizeof(M_setting),1,F_mptr); DATA1->Text=M_setting.DATA1; DATA2->Text=M_setting.DATA2; DATA3->Text=M_setting.DATA3; DATA4->Text=M_setting.DATA4; DATA5->Text=M_setting.DATA5; DATA6->Text=M_setting.DATA6; fclose(F_mptr); } //--------------------------------------------------------------------------- void __fastcall TForm1::save_settingClick(TObject *Sender) { char *f_n1=".\\set1.dat"; F_mptr=fopen(f_n1,"r "); M_setting.DATA1=StrToInt(DATA1->Text); M_setting.DATA2=StrToInt(DATA2->Text); M_setting.DATA3=StrToInt(DATA3->Text); M_setting.DATA4=StrToInt(DATA4->Text); M_setting.DATA5=StrToInt(DATA5->Text); M_setting.DATA6=StrToInt(DATA6->Text); fseek(F_mptr,0,0); fwrite(&M_setting,sizeof(M_setting),1,F_mptr); fclose(F_mptr); } </textarea>
附加檔案:46da792b9b197_test.zip
編輯記錄
kenneth_c 重新編輯於 2007-09-02 17:02:58, 註解 無‧
Stallion 重新編輯於 2007-09-02 17:06:38, 註解 將文章類型改為「問題」。‧
GGL
資深會員


發表:104
回覆:600
積分:335
註冊:2006-11-05

發送簡訊給我
#2 引用回覆 回覆 發表時間:2007-09-02 16:54:41 IP:140.118.xxx.xxx 未訂閱
這篇怎麼沒標題....而且好像沒說明問題是?
Stallion
版主


發表:52
回覆:1600
積分:1995
註冊:2004-09-15

發送簡訊給我
#3 引用回覆 回覆 發表時間:2007-09-02 17:14:58 IP:211.22.xxx.xxx 未訂閱
如果你要覆蓋存檔的話,模式應該是w。
<textarea class="cpp" rows="10" cols="60" name="code">#include #pragma hdrstop #include #include #include "Unit1.h" #include "Io.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; struct M_setting_struct { int DATA1,DATA2,DATA3,DATA4,DATA5,DATA6; }; M_setting_struct M_setting; FILE *F_mptr; //--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { } //--------------------------------------------------------------------------- void __fastcall TForm1::FormCreate(TObject *Sender) { char *f_n1=".\\set1.dat"; F_mptr=fopen(f_n1,"r "); fseek(F_mptr,0,0); fread(&M_setting,sizeof(M_setting),1,F_mptr); //永遠讀到第一個 record DATA1->Text=M_setting.DATA1; DATA2->Text=M_setting.DATA2; DATA3->Text=M_setting.DATA3; DATA4->Text=M_setting.DATA4; DATA5->Text=M_setting.DATA5; DATA6->Text=M_setting.DATA6; fclose(F_mptr); } //--------------------------------------------------------------------------- void __fastcall TForm1::save_settingClick(TObject *Sender) { char *f_n1=".\\set1.dat"; //F_mptr=fopen(f_n1,"r "); 讀取寫入模式,寫入後會一直往後增加資料檔案。 F_mptr=fopen(f_n1,"w"); M_setting.DATA1=StrToInt(DATA1->Text); M_setting.DATA2=StrToInt(DATA2->Text); M_setting.DATA3=StrToInt(DATA3->Text); M_setting.DATA4=StrToInt(DATA4->Text); M_setting.DATA5=StrToInt(DATA5->Text); M_setting.DATA6=StrToInt(DATA6->Text); fseek(F_mptr,0,0); fwrite(&M_setting,sizeof(M_setting),1,F_mptr); fclose(F_mptr); } </textarea>
kenneth_c
一般會員


發表:5
回覆:8
積分:2
註冊:2007-08-03

發送簡訊給我
#4 引用回覆 回覆 發表時間:2007-09-02 17:47:23 IP:61.61.xxx.xxx 訂閱
謝謝Stallion大大指導,但小弟試過,還是只要設值3500按save後重開,值就會亂掉耶,而設其他值就ok,實在是很不合理,不知到底那裡有問題?
Stallion
版主


發表:52
回覆:1600
積分:1995
註冊:2004-09-15

發送簡訊給我
#5 引用回覆 回覆 發表時間:2007-09-02 18:39:25 IP:211.22.xxx.xxx 未訂閱
你寫入的是數值,所以讀取寫入要以binary方式讀寫。
void __fastcall TForm1::FormCreate(TObject *Sender)
{
char *f_n1=".\\set1.dat";
F_mptr=fopen(f_n1,"rb");
fseek(F_mptr,0,0);
fread(&M_setting,sizeof(M_setting),1,F_mptr);
DATA1->Text= M_setting.DATA1;
DATA2->Text=M_setting.DATA2;
DATA3->Text=M_setting.DATA3;
DATA4->Text=M_setting.DATA4;
DATA5->Text=M_setting.DATA5;
DATA6->Text=M_setting.DATA6;
fclose(F_mptr);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::save_settingClick(TObject *Sender)
{
char *f_n1=".\\set1.dat";
F_mptr=fopen(f_n1,"wb");
M_setting.DATA1=DATA1->Text.ToInt();
M_setting.DATA2=DATA2->Text.ToInt();;
M_setting.DATA3=DATA3->Text.ToInt();;
M_setting.DATA4=DATA4->Text.ToInt();;
M_setting.DATA5=DATA5->Text.ToInt();;
M_setting.DATA6=DATA6->Text.ToInt();;
//fseek(F_mptr,0,0);
fwrite(&M_setting,sizeof(M_setting),1,F_mptr);
fclose(F_mptr);
}
//---------------------------------------------------------------------------
===================引 用 kenneth_c 文 章===================
謝謝Stallion大大指導,但小弟試過,還是只要設值3500按save後重開,值就會亂掉耶,而設其他值就ok,實在是很不合理,不知到底那裡有問題?
kenneth_c
一般會員


發表:5
回覆:8
積分:2
註冊:2007-08-03

發送簡訊給我
#6 引用回覆 回覆 發表時間:2007-09-02 19:34:46 IP:61.61.xxx.xxx 訂閱
Stallion大大,真是謝謝你的指導,數值錯誤是設定格式的問題,另外請教一下,若我格式中除了數值還有「字串」可否也用「wb」的方式儲存呢?
Stallion
版主


發表:52
回覆:1600
積分:1995
註冊:2004-09-15

發送簡訊給我
#7 引用回覆 回覆 發表時間:2007-09-02 19:43:33 IP:211.22.xxx.xxx 未訂閱
可以。不加上b的符號,那麼C程式庫會當作純文字來儲存,加上b表示以二進位值來存取。
===================引 用 kenneth_c 文 章===================
Stallion大大,真是謝謝你的指導,數值錯誤是設定格式的問題,另外請教一下,若我格式中除了數值還有「字串」可否也用「wb」的方式儲存呢?
aftcast
站務副站長


發表:81
回覆:1485
積分:1763
註冊:2002-11-21

發送簡訊給我
#8 引用回覆 回覆 發表時間:2007-09-06 06:07:43 IP:61.229.xxx.xxx 訂閱
其實這個問題和以text 或 binary 存取無關!   c 語言中的open binary 與 text 常讓人搞亂,其實無論用何種方式,當你直接對file pointer直接存取資料(無論是數值或是字串),它都是沒有分別的!   這二種方式僅差在程式或資料中有「換行」值時有差別。即 CR LF 等。原本 c 語言裡根本就不需要有什麼 binary 或 text 這二種區別!!!  是因為歷史因素才有的。什麼因素呢?  就是 unix類的os上,換行是單一個LF,而DOS上的換行則是CR LF二個byte。加上 c 語言是portable的語言,許多語法在dos上寫好原始碼後可不用改的port到unix上。問題來了…
char *s = "A\nB"; 這行若是寫入檔案中,到底是該65 13 10 66 或是65 10 66 呢? 若你以text方式寫入,則compiler會自動判別os是什麼,決定選其中一個!
想想,若世界上只有unix這個os,或是僅有dos這os,那就不會有 binary 或 text 的問題了!!! 這句話您能了解嗎?

所以…關於3500 或是3400輸入就會亂的問題,根本上應該是最後show output上的處理有些問題吧!?
------


蕭沖
--All ideas are worthless unless implemented--

C++ Builder Delphi Taiwan G+ 社群
http://bit.ly/cbtaiwan
編輯記錄
aftcast 重新編輯於 2007-09-06 06:13:44, 註解 無‧
aftcast 重新編輯於 2007-09-06 17:21:00, 註解 無‧
系統時間:2024-05-02 20:46:35
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!