CYFROWY BARON • PROGRAMOWANIE • Zobacz wątek - Odczyt z pliku o dwie linie wcześniej
Strona 2 z 3

Re: Odczyt z pliku o dwie linie wcześniej

Nowy postNapisane: wtorek, 13 stycznia 2015, 21:27
przez nvdante
Ta: playlista albumy[6]; ?
No dobra, to powinienem zamknąć to w pętli? Niestety błędy wywala nawet bez zdefiniowanego wyświetlania.
Muszę przyznać, że tego nie kumam.
Jak to powinno wyglądać w algorytmie?
- Otwieram plik
- Pobieram dane przez getline lub operator >>
- Wrzucam je w pola struktury
i co dalej? Zrobić pętlę i wyświetlić?
KOD cpp:     UKRYJ  
        for (int i=0; i<12; i++)
                {
                cout<<albumy[i].tytul;
                cout<<albumy[i].wykonawca;
                cout<<albumy[i].album;
                cout<<albumy[i].rok;
                cout<<albumy[i].cena;
                }

Tylko, że te błędy nadal są :/

Re: Odczyt z pliku o dwie linie wcześniej

Nowy postNapisane: wtorek, 13 stycznia 2015, 21:33
przez polymorphism
Jeśli tego nie kumasz, to po co używasz?!

Skoro tablica nie jest Ci potrzebna, to zdefiniuj albumy jako pojedynczy obiekt:
KOD cpp:     UKRYJ  
playlista album;

Re: Odczyt z pliku o dwie linie wcześniej

Nowy postNapisane: wtorek, 13 stycznia 2015, 21:50
przez nvdante
Samo założenie rozumiem, ale pogubiłem się w tym co napisałeś, a wolałbym wiedzieć co robię.
Zmieniłem na:
KOD cpp:     UKRYJ  
#include <iostream>
#include <windows.h>
#include <string.h>
#include <fstream>

using namespace std;

struct playlista
{
        int kolejnosc;
        string tytul;
        string wykonawca;
        string album;
        int rok;
        int cena;
};

playlista albumy;

int main()
{
        ifstream z("playlista.txt");
        string linia;
       
        while( z >> albumy.kolejnosc )
{
        getline(z, albumy.tytul);
        getline(z, albumy.wykonawca);
        getline(z, albumy.album);
        z >> albumy.rok;
        z >> albumy.cena;
}
        z.close();

        for (int i=0; i<12; i++)
                {
                cout<<albumy.tytul;
                cout<<albumy.wykonawca;
                cout<<albumy.album;
                cout<<albumy.rok;
                cout<<albumy.cena;
                }
       
        system("PAUSE");
        return 0;
}

Z tym, że w wyniku mam same 000000...

Re: Odczyt z pliku o dwie linie wcześniej

Nowy postNapisane: środa, 14 stycznia 2015, 10:16
przez polymorphism
(...) ale pogubiłem się w tym co napisałeś

No właśnie, problem w tym, że nie znasz podstaw języka, i w takim układzie ciężko jest cokolwiek wytłumaczyć. Używasz pętli, choć odnoszę wrażenie, że sam nie wiesz po co. Pisałeś, że to na zaliczenie. Co to za studia, jaki kierunek?

Re: Odczyt z pliku o dwie linie wcześniej

Nowy postNapisane: środa, 14 stycznia 2015, 10:41
przez Mironas
polymorphism napisał(a):p.s. TStrings i TIniFile pasuje tutaj jak pięść do oka.

A to niby dlaczego?
Baza danych utworów w pliku INI gdzie nazwa sekcji to unikatowy identyfikator utworu (numer kolejny):
Kod: Zaznacz cały
[1]
Tytul=Ala ma Kota
Wykonawca=Ola Piosenkowska
Album=Miauuuu
Rok=2014
Cena=50.00


ReadSections(...) - odczytujesz nazwy sekcji (czyli istniejące identyfikatory).
ReadString(...) - odczyt wybranej pozycji z wybranej sekcji.
WriteString(...) - zapis (modyfikacja) wybranej pozycji w dowolnej sekcji.
EraseSection(...) - usunięcie sekcji (utworu).

Do pliku dodałbym też sekcję "systemową" gdzie trzymałbym np ostatnio użyty nr kolejny utworu.

Może być coś prostszego? Oczywiście nie wiedziałem, że jest odgórny wymóg, aby użyć strumieni.

Re: Odczyt z pliku o dwie linie wcześniej

Nowy postNapisane: środa, 14 stycznia 2015, 10:42
przez nvdante
polymorphism napisał(a):Pisałeś, że to na zaliczenie. Co to za studia, jaki kierunek?

A co to za różnica jakie studia i kierunek? Mam napisać program, co ma się w nim znaleźć jest jasno określone, więc skoro masz większe doświadczenie i widzisz, że gdzieś popełniam błąd to po prostu napisz "tu robisz źle". Nie trzeba od razu wytykać, że ktoś wie mniej, bo to, że słuchasz muzyki nie musi oznacza, że umiesz komponować.

Wracając do problemu. Pętli używam do dwóch rzeczy, do pobrania danych do odpowiednich pól oraz do ich wyświetlenia.
Problem jednak w tym, że pojawiają mi się dane szczątkowe, dokładniej:
Kod: Zaznacz cały
kolejność // zawsze 0, a powinna być konkretna liczba
tytuł
wykonawca
0
0

A powinno być:
Kod: Zaznacz cały
kolejność
tytuł
wykonawca
album // to pole jest pomijane
rok // od tą są zera w wyniku
cena

Wygląda na to, że część pól została wycięta, a część zamiast wyświetlić konkretną liczbę podała 0.
Poza tym ten kod powoduje przewałkowanie tylko pierwszych 6 linii kodu, pozostałe są kompletnie pomijane ( widzę po tym, że tytuł jest cały czas ten sam ).
Czy możesz naprowadzić mnie na właściwą drogę co jest nie tak? Wydawało mi się, że takie problemy mogą się pojawić, gdy mam litery, a próbuję wyświetlić jako int, ale w konkretnych polach są cyfry.

Ps.: Przed chwilą zrobiłem małą zmianę, otóż zdublowałem wiersz pobierający przez getline zmienną do albumy.wykonawca. Ta operacja spowodowała, że wszystkie pola zapełniły się prawidłowymi danych, wszystkie dane z pliku zostały pobrane i prawidłowo wyświetlone. Mam dlatego pytanie: dlaczego zdublowanie tej linii pomogło?
Kod potwierdzający to:
KOD cpp:     UKRYJ  
                                z >> albumy.kolejnosc;
                                getline(z, albumy.tytul);
                                getline(z, albumy.wykonawca);
                                getline(z, albumy.wykonawca);
                                getline(z, albumy.album);
                                z >> albumy.rok;
                                z >> albumy.cena;

Dane wynikowe:
Kod: Zaznacz cały
0
Michael Jackson
Ben
1972
100
1
Michael Jackson
Thriller
1991
100

Re: Odczyt z pliku o dwie linie wcześniej

Nowy postNapisane: środa, 14 stycznia 2015, 11:35
przez polymorphism
Mironas napisał(a):A to niby dlaczego?

W przypadku INI trzeba przeedytować plik - dojdzie dużo zbędnych rzeczy, jak nazwy wartości. Format danych w pliku podanym przez nvdante jest prosty i można bez problemu odczytać go za pomocą istream. W przypadku TStrings podobnie - po co tworzyć listę linii jeśli można od razu czytać (linie) do struktur, do odpowiednich pól?

A co to za różnica jakie studia i kierunek?

Różnica żadna, zwykła ciekawość ;)

Co do reszty, pokaż dane wejściowe.

Re: Odczyt z pliku o dwie linie wcześniej

Nowy postNapisane: środa, 14 stycznia 2015, 11:38
przez nvdante
Plik playlista.txt ma takie dane:
Kod: Zaznacz cały
0
Ben
Michael Jackson
Ben
1972
100
1
Thriller
Michael Jackson
Thriller
1991
100

Re: Odczyt z pliku o dwie linie wcześniej

Nowy postNapisane: środa, 14 stycznia 2015, 11:58
przez Mironas
polymorphism napisał(a):W przypadku INI trzeba przeedytować plik - dojdzie dużo zbędnych rzeczy, jak nazwy wartości.

Nikt nie mówił, że chodzi o istniejący już plik do obsługi którego robimy aplikację.
Zwykle format zapisu danych w pliku ustalany jest przez programistę który robi aplikację.

Re: Odczyt z pliku o dwie linie wcześniej

Nowy postNapisane: środa, 14 stycznia 2015, 12:04
przez polymorphism
Dobra już wiem gdzie leży problem. Chodzi o to, że operator >> nie ściąga znaku końca linii (generalnie nie ściąga znaku na którym kończy skanowanie), przez co getline czyta pustą linie. Wszystko się przesuwa i mamy totalny fuck up.

Tak powinno być ok:
KOD cpp:     UKRYJ  
    while( z >> albumy.kolejnosc )
    {
        z.ignore((unsigned)-1, '\n');
        getline(z, albumy.tytul);
        getline(z, albumy.wykonawca);
        getline(z, albumy.album);
        z >> albumy.rok;
        z >> albumy.cena;

        cout<< albumy.tytul << '\n';
        cout<< albumy.wykonawca << '\n';
        cout<< albumy.album << '\n';
        cout<< albumy.rok << '\n';
        cout<< albumy.cena << '\n';
    }

Re: Odczyt z pliku o dwie linie wcześniej

Nowy postNapisane: środa, 14 stycznia 2015, 12:15
przez nvdante
Niestety w wyniku dostaję:
Kod: Zaznacz cały
(pusta linia)
Ben
Michael Jackson
0
0

czyli wygląda na to, że pominął linię albumy.album i wyciął dane.

Re: Odczyt z pliku o dwie linie wcześniej

Nowy postNapisane: środa, 14 stycznia 2015, 13:00
przez polymorphism
Ciekawa sprawa, bo w Visualu to działa, a w Code::Blocks nie. Na logikę visual jest tu bardziej wiarygodny.

Re: Odczyt z pliku o dwie linie wcześniej

Nowy postNapisane: środa, 14 stycznia 2015, 13:06
przez nvdante
Masz pomysł dlaczego tak się dzieje lub co mogę dalej zrobić?
Może jakoś inaczej spróbujemy odczytać dane? Właściwie chodzi tylko o to, żeby wyświetlone były te, które spełnią warunek wpisany przez użytkownika, czyli wykonawca == X.

Ps.: W związku z tym, że mogę zaprogramować inny sposób zapisu może wybranie opcji pliku binarnego by pomogło do odczytu?

Re: Odczyt z pliku o dwie linie wcześniej

Nowy postNapisane: środa, 14 stycznia 2015, 13:26
przez polymorphism
Dobra już mam. Zmień pierwszy parametr ignore:
KOD cpp:     UKRYJ  
(unsigned)-1

na bardziej prawilny:
KOD cpp:     UKRYJ  
std::numeric_limits<std::streamsize>::max()

W czym rzecz. W obu przypadkach, i w VC, i w C::B, pierwszy parametr jest typu std::streamsize. W swej naiwności założyłem, że typ ten jest typem unsigned (no bo jak rozmiar strumienia może być ujemny?), i tu był mój błąd. Typ ten, nie wiedzieć czemu, jest typem ze znakiem. Dlaczego w VC działało, a w C::B nie: w visualu typ streamsize jest typem 64-bitowym, przypisanie (unsigned)-1 da w efekcie wartość 4294967295. Z kolei w C::B (mingw) streamsize jest 32-bitowy, przypisanie (unsigned)-1 da w parametrze wartość -1, i dlatego to nie działało.

Teraz powinno być ok.

Re: Odczyt z pliku o dwie linie wcześniej

Nowy postNapisane: środa, 14 stycznia 2015, 13:39
przez nvdante
Faktycznie działa dobrze. Bardzo dziękuję :)
Swoją drogą czy dobrze rozumiem, że skompilowanie poprzedniego kodu w mingw 64bit powinno działać prawidłowo?
Bo Dev-c++ też wykorzystuje mingw, więc to pewnie właśnie w tym tkwił problem, jak mówiłeś.