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

question-closed Problem ze strumieniem do pliku [C++]

Object Storage Arubacloud
+2 głosów
465 wizyt
pytanie zadane 7 lipca 2015 w C i C++ przez niezalogowany
zamknięte 8 lipca 2015

Witam, mam mały problem z moim strasznie prostym, aczkolwiek niedziałającym programikiem :|

Jest to programik do sprawdzania ile razy włączyłem komputer w roku szkolnym (dam go do automatycznego uruchamiania przy starcie pod koniec wakacji ;)).

No więc oto problem: tworzę strumień wyjściowy i wejściowy, następnie wyciągam z pliku liczbę do mojej zmiennej, zwiększam ją o jeden (oj, no inkrementuję ;)) a następnie chciałbym ją znowu włożyć do pliku (nie używam trybu ios::app, czyli że plik się nadpisze nową liczbą). No więc zmienna liczbę z pliku pobiera, ale już jej nie chce z powrotem do tego samego pliku włożyć O_o Na początek do pliku dałem liczbę 10. Następnie ją inkrementuję i na ekranie widać 11. Jak włączam program drugi raz, znowu jest 11, czyli że na początku pobrało 10. Patrzę do pliku (tak żeby się upewnić) a tam oczywiście spokojnie sobie siedzi 10 :|

Oto mój kod:

#include <iostream>
#include <stdio.h>
#include <fstream>
#include <cstdlib>

using namespace std;

int liczbaWlaczen;
fstream plik;

int main()
{
    plik.open("licznik.txt",ios::out|ios::in);
    if(!plik.good())
    {
        cout << "!ERROR! Plik nie istnieje.";
        getchar();

        return 0;
    }

    plik >> liczbaWlaczen;
    liczbaWlaczen++;
    plik << liczbaWlaczen;

    cout << "Witaj! Od pocz\245tku roku szkolnego w\210\245czy\210e\230 komputer: " << liczbaWlaczen;
    getchar();

    plik.close();
    plik.clear();

    return 0;
}

Jedyne co mi zostało w tym programie, to ładnie sformatowane literki i naprawienie tego problemu (no, może kiedyś bym go sobie przerobił do SFML-a, byłoby fajnie ;)), który na pewno jest strasznie prosty, ale ja go nie umię znaleźć, bo niezbyt lubię pracę z plikami, a przynajmniej nie pociągało mnie tak bardzo. Dlatego teraz chcę się trochę w tym poduczyć ;)

Dzięki za odpowiedzi na to proste pytanie ;)

komentarz zamknięcia: Problem rozwiązany, już działa ;)

3 odpowiedzi

0 głosów
odpowiedź 7 lipca 2015 przez Wiciorny Ekspert (269,710 p.)
wybrane 7 lipca 2015
 
Najlepsza

Wziąłem kod na warsztat. Generalnie- program nie dziala, bo za kazdym  nowym uruchomieniem/  plik sie tworzy jakby na nowo. 

Rozdzieliłem ten kod, aby po odczytaniu i zapisie wartosci ... potem otworzyl do zapisu ( tak aby mozna bylo to nadpisywac ).

#include <iostream>
#include <stdio.h>
#include <fstream>
#include <cstdlib>
#include <string>

using namespace std;






int main()

{
    int liczbaWlaczen;
    fstream plik;
    plik.open("licznik.txt",ios::in);

    if(plik.good()==false)
    {
    cout<<"! ERROR! PLIK nie istnieje.";
    getchar();
    return 0;

    }
    plik>>liczbaWlaczen;
    cout<<"Sprawdzam wartosc: "<<liczbaWlaczen<<endl;
    liczbaWlaczen+=1;
    plik.close();
    plik.open("licznik.txt",ios::out);

    plik<<liczbaWlaczen;
    plik.close();
    plik.clear();

cout<<"Witaj Od poczatku roku szkulonego wlaczyles komputer: "<<liczbaWlaczen<<" razy. "<<endl;
getchar();



return 0;

}

działa poprawnie 

komentarz 7 lipca 2015 przez Wiciorny Ekspert (269,710 p.)
Nie można było po odczycie zapisać jednocześnie bo program gubił się o którą liczbeWlaczeń chodzi.

Na linuxie lepszy wysyp był, w windowsie... nie było błędy więc to zostawało pomijane i zapisanie nie nastąpiło.
komentarz 7 lipca 2015 przez adrian17 Ekspert (344,860 p.)
Jak program może się pogubić "o jaką liczbeWlaczen chodzi"?
komentarz 7 lipca 2015 przez niezalogowany
Hm :| W sumie to nie wpadłem na taki prosty pomysł. Sprawdzę to, dzięki ;)
komentarz 7 lipca 2015 przez niezalogowany
Super, działa, dzięki za prosty pomysł ;)
0 głosów
odpowiedź 7 lipca 2015 przez 0e85dc6eaf Dyskutant (8,840 p.)
Spróbuj przekonwertować to do inta, bo z pliku pobierasz to jako string
komentarz 7 lipca 2015 przez niezalogowany
Też tak myślałem, że jak wezmę to z pliku, to program to zrozumie jako ciąg znaków i się wysypie, ale konsolka się pokazała, program się włączył, więc już o tym za bardzo nie myślałem :| Dzięki za pomysł, za niedługo sprawdzę ;)
0 głosów
odpowiedź 7 lipca 2015 przez adrian17 Ekspert (344,860 p.)

Odpowiedzi mówiące o "pobieraniu jako string" nie mają sensu, operator>> jest przeładowany dla intów i większości podstawowych typów.

Ogólnie używanie tego strumienia do czytania i pisania nie jest najlepszym pomysłem, ale jeśli już to robisz, operacje czytania należy rozdzielać seekiem. Taka wersja (z dodanym plik.seekg(0)) działa u mnie:

 

#include <iostream>
#include <cstdio>
#include <fstream>

using namespace std;

int main()
{
    std::fstream plik("licznik.txt", ios::out|ios::in);
    if(!plik)
    {
        cout << "!ERROR! Plik nie istnieje.";
        getchar();

        return 0;
    }
    int liczbaWlaczen;
    plik >> liczbaWlaczen;

    liczbaWlaczen++;

    plik.seekg(0);
    
    plik << liczbaWlaczen;

    cout << "Witaj! Od pocz\245tku roku szkolnego w\210\245czy\210e\230 komputer: " << liczbaWlaczen;
    getchar();
}

 

komentarz 7 lipca 2015 przez niezalogowany
Właśnie, jeśli chodzi o to, że program pobiera tekst jako string to tak myślałem na początku, ale program się włączył, więc o tym zapomniałem ;) Ale mam małe pytanie: przecież funkcja seekg() ustawia "wskaźnik" do czytania tekstu na początku pliku, więc nie wiem czemu miałoby to działać :| Skoro działa to super! Sprawdzę za niedługo, ale wytłumacz mi proszę, czemu ta funkcja pomaga w tym przypadku.
komentarz 7 lipca 2015 przez Wiciorny Ekspert (269,710 p.)
udalo mi sie naprawic to rozdzielajac kod jak wyzej podałem
komentarz 7 lipca 2015 przez adrian17 Ekspert (344,860 p.)
Jasne, można też zrobić dwa niezależne strumienie, jak zrobiłeś...

To co pokazałem działa, bo:

1. Standard wymaga, żeby między wejściem a wyjściem na tym samym otwartym pliku wywołać jedną z funkcji `fflush, fseek`, etc (a odpowiednikiem tej drugiej w C++ jest właśnie `file.seekp` i `file.seekg`).

2. Pozycja zapisu i odczytu jest wspólna, zmieniając jedną zmienia się też druga. `seekg(0)` możesz tu zastąpić `seekp(0)` i będzie działać tak samo.
komentarz 7 lipca 2015 przez niezalogowany

O! To dzięki za informację, ale jednak tamten zapis wydaję mi się łatwiejszy, także do zrozumienia, ale dałem ci yes za info ;)

Podobne pytania

0 głosów
1 odpowiedź 1,088 wizyt
+1 głos
2 odpowiedzi 131 wizyt
0 głosów
1 odpowiedź 1,963 wizyt

92,555 zapytań

141,404 odpowiedzi

319,557 komentarzy

61,940 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.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...