• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Błąd w zapisanym pliku przy wyłączeniu komputera

0 głosów
281 wizyt
pytanie zadane 11 lipca 2017 w C i C++ przez Szymon195 Nowicjusz (120 p.)

Mam taki program który właściwie jest najprostszym zegarkiem liczącym czas pracy komputera. Działa on na zasadzie zapisu czasu co sekundę do pliku i jego odczytu. Wszystko działa kiedy komputer wyłączam normalnie. Jednak kiedy komputer straci zasilanie lub zostanie wyłączony z "guzika" to plik w którym program przechowuje czas ulega jakiemuś błędowi i jego wartość zmienia się na NUL przez co program nie może wczytać czasu po ponownym włączeniu. Może ktoś wie co zrobić w takiej sytuacji ?

//---------------------------------------------------------------------------


#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
#include <iostream>
#include <fstream.h>
#include <conio.h>

//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "trayicon"
#pragma resource "*.dfm"
#include <fstream.h>
TForm1 *Form1;

int s;
int dzien,godzin, minut, sekund,g;
AnsiString d,godz,m,sek;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{

}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
Timer1->Enabled=true;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{

string line1;
AnsiString line2;
string linia1;
AnsiString linia2;

fstream plik;
plik.open("czas.txt",ios::in);
getline(plik,linia1);
linia2 = linia1.c_str();
s=StrToInt(linia2);
plik.close();

s++;


plik.open("czas.txt",ios::out);
plik<<s<<endl;
plik.close();

 dzien = s/86400;
 d=IntToStr(dzien);
 if(dzien<10) {d="0"+d;}

 godzin = (s-dzien*86400)/3600;
 godz = IntToStr(godzin);
 if(godzin<10) {godz="0"+godz;}

 g=s/3600;

 minut = (s-g*3600)/60;
 m = IntToStr(minut);
 if(minut<10) {m="0"+m;}

 sekund = s-g*3600-minut*60;
 sek = IntToStr(sekund);
 if(sekund<10) {sek="0"+sek;}


 Label1->Caption = d+":"+godz+":"+m+":"+sek;

 if(s<=0)
 {
  Label1->Caption="KONIEC CZASU";
  Timer1->Enabled=false;
 }

}
//---------------------------------------------------------------------------

void __fastcall TForm1::TrayIcon1Create(TObject *Sender)
{
Show();
Application->BringToFront();
}
//---------------------------------------------------------------------------


void __fastcall TForm1::Button2Click(TObject *Sender)
{
Timer1->Enabled=false;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button4Click(TObject *Sender)
{
ShowMessage("Czy na pewno chcesz zresetowac wynik");
Timer1->Enabled=false;
Label1->Caption = "00:00:00:00";
fstream plik;
plik.open("czas.txt",ios::out);
plik<<0<<endl;
plik.close();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::TrayIcon1Click(TObject *Sender)
{
Show();
Application->BringToFront();
}
//---------------------------------------------------------------------------


void __fastcall TForm1::Timer2Timer(TObject *Sender)
{
fstream plik2;
plik2.open("czas2.txt",ios::out);
plik2<<s<<endl;
plik2.close();
}
//---------------------------------------------------------------------------

 

komentarz 12 lipca 2017 przez MsMaciek123 Pasjonat (24,760 p.)

Spróbój tak

//---------------------------------------------------------------------------
 
 
#include <vcl.h>
#pragma hdrstop
 
#include "Unit1.h"
#include <iostream>
#include <fstream.h>
#include <conio.h>
 
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "trayicon"
#pragma resource "*.dfm"
#include <fstream.h>
TForm1 *Form1;
 
int s;
int dzien,godzin, minut, sekund,g;
AnsiString d,godz,m,sek;
 string line1;
AnsiString line2;
string linia1;
AnsiString linia2;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
 
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
Timer1->Enabled=true;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
fstream plik;
plik.open("czas.txt",ios::in);
getline(plik,linia1);
linia2 = linia1.c_str();
s=StrToInt(linia2);
plik.close();
 
s++;
 
 
plik.open("czas.txt",ios::out);
plik<<s<<endl;
plik.close();
 
 dzien = s/86400;
 d=IntToStr(dzien);
 if(dzien<10) {d="0"+d;}
 
 godzin = (s-dzien*86400)/3600;
 godz = IntToStr(godzin);
 if(godzin<10) {godz="0"+godz;}
 
 g=s/3600;
 
 minut = (s-g*3600)/60;
 m = IntToStr(minut);
 if(minut<10) {m="0"+m;}
 
 sekund = s-g*3600-minut*60;
 sek = IntToStr(sekund);
 if(sekund<10) {sek="0"+sek;}
 
 
 Label1->Caption = d+":"+godz+":"+m+":"+sek;
 
 if(s<=0)
 {
  Label1->Caption="KONIEC CZASU";
  Timer1->Enabled=false;
 }
 
}
//---------------------------------------------------------------------------
 
void __fastcall TForm1::TrayIcon1Create(TObject *Sender)
{
Show();
Application->BringToFront();
}
//---------------------------------------------------------------------------
 
 
void __fastcall TForm1::Button2Click(TObject *Sender)
{
Timer1->Enabled=false;
}
//---------------------------------------------------------------------------
 
void __fastcall TForm1::Button4Click(TObject *Sender)
{
ShowMessage("Czy na pewno chcesz zresetowac wynik");
Timer1->Enabled=false;
Label1->Caption = "00:00:00:00";
fstream plik;
plik.open("czas.txt",ios::out);
plik<<0<<endl;
plik.close();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::TrayIcon1Click(TObject *Sender)
{
Show();
Application->BringToFront();
}
//---------------------------------------------------------------------------
 
 
void __fastcall TForm1::Timer2Timer(TObject *Sender)
{
fstream plik2;
plik2.open("czas2.txt",ios::out);
plik2<<s<<endl;
plik2.close();
}
//---------------------------------------------------------------------------

 

2 odpowiedzi

0 głosów
odpowiedź 11 lipca 2017 przez niezalogowany
(uwaga na boku) coś ostatnio jest sporo śmiecio-buildera :(

Przy normalnym zamknięciu wysyłąny jest sygnał KILL do wszystkich procesów, więc handle na pliki zamykane są normalnie dlatego też nie masz błędów przy zapisie.

Przy odcięciu zasilania ten sygnał nie zostaje wysłany, a sam plik może być w danym momencie w nieokreślonym stanie stąd błędy.

Jedyny sposób to weryfikacja poprawności zamknięcia ostatniej wartości, co za tym idzie powinieneś robić co jakiś czas np backup zapisywanej wartości
0 głosów
odpowiedź 12 lipca 2017 przez j23 Mędrzec (195,220 p.)

Działa on na zasadzie zapisu czasu co sekundę do pliku

Mierzenie czasu na podstawie zdarzeń timera okienkowego nie jest dobrym pomysłem. Do pomiaru czasu użyj std::chrono::system_clock i innych klas z biblioteki std::chrono. Timer jest dobry do wykonywania czynności co jakiś przybliżony czas.

Podobne pytania

+1 głos
2 odpowiedzi 1,448 wizyt
pytanie zadane 21 marca 2021 w C# przez piter11251 Obywatel (1,300 p.)
0 głosów
1 odpowiedź 684 wizyt
0 głosów
1 odpowiedź 397 wizyt
pytanie zadane 1 listopada 2018 w C i C++ przez eee Nowicjusz (120 p.)

93,758 zapytań

142,716 odpowiedzi

323,364 komentarzy

63,357 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj

Twierdza Linux. Bezpieczeństwo dla dociekliwych

Aby uzyskać rabat -10%, użyjcie kodu pasja-linux, wpisując go w specjalne pole w koszyku.

...