• 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++]

Cloud VPS
+2 głosów
881 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 (281,450 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 (281,450 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 Mentor (354,120 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 Mentor (354,120 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 (281,450 p.)
udalo mi sie naprawic to rozdzielajac kod jak wyzej podałem
komentarz 7 lipca 2015 przez adrian17 Mentor (354,120 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,727 wizyt
+1 głos
2 odpowiedzi 355 wizyt
0 głosów
1 odpowiedź 2,391 wizyt

93,460 zapytań

142,454 odpowiedzi

322,724 komentarzy

62,837 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

Kursy INF.02 i INF.03
...