Jak korzystać z plików?

Jak korzystać z plików?
KA
  • Rejestracja:ponad 5 lat
  • Ostatnio:około 5 lat
  • Postów:19
0

Cześć
Na wstępie - pisałam w C++ kilka dobrych lat temu, wtedy ostatecznie skorzystałam z funkcji dostępu do plików żywcem wziętych z C. Obecnie chcę pisać czysto w C++... 'botak'.
Problem: nie wiem jak korzystać z plików: Dawno temu jak się uczyłam pisać to nauczyłam sie korzystać z try catch i łapania wyjątków, tak jak tu:

Kopiuj
bool fileexists(string nazwapliku) {
       ifstream plik;
       try {
               plik.open(nazwapliku, ios::in);
               if(plik.good()) {
                        plik.close();
                        return(true);
               } else { return(false);}
        } catch (exception& e) {
               cout << e.what() << endl;
               return(false);
        }
}

Ale na necie znalazłam coś takiego:

Kopiuj
if(plik.good()) {rób swoje}
else
  {rób coś innego}

To drugie rozwiązanie nie pozwala na wyłapanie nic?

Kolejna sprawa - zrobiłam się ciekawska i muszę wiedzieć CO robi każde polecenie. A wiec zapisuję sobie coś do pliku:

Kopiuj
pwyj.write((char*)&znak,1);

I czytam:

Kopiuj
pwej.read((char*)&znak,1);

Dlaczego definiując wskaźnik korzystam z typu i po co to robić? Co tu porabia "(char*)" właściwie? Na co mi adres &znak ? (dobrze rozumiem, żę to wskazuje adres zmiennej do/z której ma być pobrana wartość? 1 jak rozumiem to wielkość przesyłanej zmiennej, ok.

edytowany 3x, ostatnio: hauleth
_13th_Dragon
  • Rejestracja:ponad 19 lat
  • Ostatnio:3 miesiące
1

Co do pierwszego pytania, to w dokumentacji napisano jasne i wyraźnie
Co do drugiego ..
metody read i write przyjmują char* oraz ile bajtów od tego miejsca czytać/pisać.
Więc pobieramy adres tego znaku w pamięci i odczytujemy/zapisujemy jeden znak.
W przypadku jeżeli znak ma typ char konwersja na (char*) jest zbędna.


Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.
KA
  • Rejestracja:ponad 5 lat
  • Ostatnio:około 5 lat
  • Postów:19
0

Dzieki za odpowiedź na II pytanie, jednak nadal mam wątpliwości co do I.
Gdybym znalazła odpowiedź na I pytanie to bym nie pytała. Poza tym interesuje mnie zdanie osób, które w C++ piszą na co dzień i wiedzą z doświadczenia z czego warto i należy korzystać.

_13th_Dragon
  • Rejestracja:ponad 19 lat
  • Ostatnio:3 miesiące
0

http://www.cplusplus.com/reference/fstream/ifstream/open/

Return Value
none
If the function fails to open a file, the failbit state flag is set for the stream (which may throw ios_base::failure if that state flag was registered using member exceptions).

Exception safety
Basic guarantee: if an exception is thrown, the stream is in a valid state.
It throws an exception of member type failure if the function fails (setting the failbit state flag) and member exceptions was set to throw for that state.


Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.
tajny_agent
  • Rejestracja:ponad 11 lat
  • Ostatnio:ponad rok
  • Postów:1340
0

BTW C++17 ma już gotową funkcję do sprawdzania czy plik istnieje -> std::filesystem::exists


"I love C++. It's the best language in the world right now for me to write the code that i need and want to write"
~ Herb Sutter
vpiotr
Exists ma ograniczone zastosowanie bo po sprawdzeniu, ale przed reakcja na wynik moze ktos stworzyc rownolegle szukany plik.
ZK
  • Rejestracja:około 19 lat
  • Ostatnio:4 miesiące
0

ja wrzucę tutaj swój kod na działaniu na plikach. Nie pamiętam czy mam funkcję sprawdzającą czy plik istnieje ale na pewno jest odczyt/zapis

plik zbiornik.h

Kopiuj
#ifndef ZBIORNIK_H
#define ZBIORNIK_H

class zbiornik
{
private:
    float pojemnosc_zbiornika, poprzedni_stan_licznika, obecny_stan_licznika;
    float ilosc_wody, pobierz, jaki_jest_stan_wody_zbiornika;
    //bool zawor1, zawor2;

    int stan_wody_w_zbiorniku ();
    void napelnij_zbiornik ();
    int licznik ();
    int zapamietaj_stany();

public:
    //float pojemnosc_zbiornika;
    int pobierz_wode_ze_zbiornika(float);
};

#endif // ZBIORNIK_H

plik zbiornik.cpp

Kopiuj
#include <fstream>
#include <string.h>
#include <stdlib.h>
#include "zbiornik.h"
#include <iostream>

using namespace std;

int zbiornik::pobierz_wode_ze_zbiornika(float pobieraj)
{
    pobierz = pobieraj;
    pojemnosc_zbiornika = 100.0f; /*litrów*/

    if (pobierz > pojemnosc_zbiornika)
    {
        cout << "Nie można wybrać większej ilości wody niż pojemność zbiornika" << endl;
        cout << "wylewam MAX " << pojemnosc_zbiornika << " litrów" << endl;
        cout << endl;
        pobierz_wode_ze_zbiornika(pojemnosc_zbiornika);
        cout << endl;
    }

    /*else if (jaki_jest_stan_wody_zbiornika < pobierz)
    {
        cout << "Wylewam " << jaki_jest_stan_wody_zbiornika << " litrów";
        cout << endl;
        pobierz_wode_ze_zbiornika(jaki_jest_stan_wody_zbiornika);
        cout << endl;
    }*/

    else if (pobierz < 0)
    {
        cout << "Nie można pobrać takiej ilości wody" << endl;
    }

    else
    {
    //ile wody zostało w zbiorniku po wylaniu przez użytkownika
        ilosc_wody = pojemnosc_zbiornika - pobierz;

        zapamietaj_stany();
    }

    return ilosc_wody;
}

inline int zbiornik::licznik()
{
    //zliczanie ile wybrano wody
    this->obecny_stan_licznika = this->poprzedni_stan_licznika + this->pobierz;

    return this->obecny_stan_licznika;
}

inline int zbiornik::stan_wody_w_zbiorniku()
{
    //obliczanie ile zostało wody w zbiorniku
    this->jaki_jest_stan_wody_zbiornika = this->ilosc_wody - this->pobierz;

    return this->jaki_jest_stan_wody_zbiornika;
}

int zbiornik::zapamietaj_stany()
{
    fstream wczytaj_licznik_txt, wczytaj_stan_zbiornika_txt;
    ofstream zapisz_licznik_txt, zapisz_stan_zbiornika_txt;

    wczytaj_licznik_txt.open("licznik.txt", ios_base::out | ios_base::in);

    //wczytywanie stanu licznika i zapisywanie stanu licznika
    if (wczytaj_licznik_txt.is_open() == true)
    {
        string wczytaj_stan_licznika_z_pliku;
        getline(wczytaj_licznik_txt, wczytaj_stan_licznika_z_pliku);

        cout << "stan licznika - " << wczytaj_stan_licznika_z_pliku << endl;

        float conversion = atof(wczytaj_stan_licznika_z_pliku.c_str());

        poprzedni_stan_licznika = conversion;

        licznik();

        cout << "stan licznika po wylaniu " << pobierz << " litrów wody " << obecny_stan_licznika << endl;

        zapisz_licznik_txt.open("licznik.txt", ios_base::out | ios_base::in | ios_base::trunc);
        zapisz_licznik_txt << obecny_stan_licznika;

        cout << endl;

        wczytaj_licznik_txt.close();
        zapisz_licznik_txt.close();
    }

    else
    {
        cout << "Błąd otwarcia pliku - licznik.txt" << endl;
    }

        wczytaj_stan_zbiornika_txt.open("stan.txt", ios_base::out | ios_base::in);

    //wczytywanie stanu zbiornika i zapisywanie stanu zbiornika

    if (wczytaj_stan_zbiornika_txt.is_open() == true)
    {
        string wczytaj_stan_zbiornika_z_pliku;
        getline(wczytaj_stan_zbiornika_txt, wczytaj_stan_zbiornika_z_pliku);

        cout << "stan zbiornika - " << wczytaj_stan_zbiornika_z_pliku << endl;

        float conversion = atof(wczytaj_stan_zbiornika_z_pliku.c_str());

        ilosc_wody = conversion;

        stan_wody_w_zbiorniku();

        cout << "stan wody w zbiorniku po wylaniu - " << pobierz << " litrów wody " << jaki_jest_stan_wody_zbiornika << endl;

        zapisz_stan_zbiornika_txt.open("stan.txt", ios_base::in | ios_base::out | ios_base::trunc);
        zapisz_stan_zbiornika_txt << jaki_jest_stan_wody_zbiornika;

        wczytaj_stan_zbiornika_txt.close();
        zapisz_stan_zbiornika_txt.close();

        napelnij_zbiornik();
    }

    else
    {
        cout << "Błąd otwarcia pliku - stan.txt" << endl;
    }

return 1;
}

void zbiornik::napelnij_zbiornik()
{
    if (jaki_jest_stan_wody_zbiornika <= 20)
    {
        cout << endl;
        cout << "Napelniam zbiornik" << endl;

        ofstream napelnij;
        napelnij.open("stan.txt", ios_base::out | ios_base::in | ios_base::trunc);
        napelnij << pojemnosc_zbiornika;

        napelnij.close();
    }

    else
    {
        cout << endl;
        cout << "Zbiornik jest pełny" << endl;
    }
}

plik main.cpp

Kopiuj
#include <iostream>
#include "zbiornik.h"

using namespace std;

int main ()
{
    zbiornik *podaj_ile_chcesz_wody;
    cout << "Ile chcesz pobrac wody ?" << endl;
    float ile;
    cin >> ile;
    //podaj_ile_chcesz_wody.pobierz_wode_ze_zbiornika(ile);
    podaj_ile_chcesz_wody = new zbiornik();
    podaj_ile_chcesz_wody->pobierz_wode_ze_zbiornika(ile);
}

Sądzę, że może to być dla ciebie bardzo pomocne


bla
edytowany 1x, ostatnio: zkubinski
_13th_Dragon
Czukcza nie chce być czytelnikiem, Czukcza chce być pisarzem!
ZK
ty to chyba nie masz nic ciekawego do roboty co ? zazdrość ciebie jakaś bierze ? bo mi to zwisa xD
_13th_Dragon
Zazdrość o co? O brak pojęcia o czym mówisz? O totalny brak wiedzy? O niezdolność nauczyć się czemukolwiek przez uznanie siebie istotą bezbłędną? O nieprzyjęcie czytania dokumentacji?
ZK
już powiedziałem czemu służy dokumentacja, jesteś odporny na argumenty, nie uważam się za istotę bezbłędną, raczej to ty mnie się czepiasz nie wiedzieć czemu i uważasz, że zjadłeś wszystkie rozumy. Udowodnij swój kunszt w wątkach które dotyczą Qt, a nie podstaw C++. Przykład dałem po to, bo założyłem również, że autor wątku nie wie jak korzystać z metody odczyt/zapis do pliku, bo w sumie da się to wyczuć z treści posta

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.