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

PROBLEM: Odczyt z pliku tekstowego

Mały hosting, OGROMNE możliwości
0 głosów
858 wizyt
pytanie zadane 28 maja 2015 w C i C++ przez Wiktor Stary wyjadacz (11,120 p.)

Witam, otóż mam taki problem z kodem z odcinka o odczycie pliku. Chodzi mi o to, że nie wiem co w całym kodzie robi instrukcja switch.

#include <iostream>
#include <fstream>
#include <cstdlib>

using namespace std;

string imie, nazwisko;
int nr_tel;

int main()
{
system("color 1f");
system("chcp 1250>nul");



    fstream plik;
    plik.open("wizytowka.txt",ios::in);

    if(plik.good()==false)
    {
        cout<<"Plik nie istnieje!";
        exit(0);
    }


    string odczytany_tekst;
    int nr_linii=1;

    while(getline(plik, odczytany_tekst))
    {
        switch(nr_linii)
    {
        case 1: imie = odczytany_tekst; break;
        case 2: nazwisko = odczytany_tekst; break;
        case 3: nr_tel = atoi(odczytany_tekst.c_str()); break;
    }

    nr_linii++;
}


cout<<imie<<endl;
cout<<nazwisko<<endl;
cout<<nr_tel<<endl;



plik.close();

system("PAUSE>nul");
return 0;
}

Mógłby mi ktoś to szczegółowo opisać?

Pozdrawiam. smiley

4 odpowiedzi

+1 głos
odpowiedź 28 maja 2015 przez Kozerski Igor Użytkownik (610 p.)
case sprawdza linie tutaj, jeśli jest pierwsza to przepisuje do zmiennej imie, druga linia jest przypisywana do zmiennej nazwisko, a 3 linia przypisuje do zmiennej nr_tel

pozdrawaim
+1 głos
odpowiedź 28 maja 2015 przez MrWeb Stary wyjadacz (10,180 p.)
Dane do odczytania w pliku tekstowym są zapisywane w powtarzalnym formacie

imie

nazwisko

nr_telefonu

Program odczytuje ten plik linia po linii (funkcja getline() ), ale żeby program się zorientował którą część wizytówki aktualnie odczytuje, użyta została instrukcja switch i zmienna nr_linii;

Dzięki temu program po otworzeniu pliku odczytuje pierwszą linię (imię) i na podstawie stanu zmiennej nr_linii program określa gdzie odczytany tekst ma zapisać (w tym przypadku do zmiennej odczytany_tekst (linia 34)

Potem odczytuje następną linię (nazwisko) i na podstawie stanu zmiennej nr_linii (która wcześniej została zwiększona o 1) program znowu określa gdzie odczytany tekst ma zapisać ( nr linii 35)

Potem to samo, zmienna nr_linii jest zwiększana, tak, że instrukcja swich pozwala na wykonanie kodu jedynie z linii nr 36. Ta linia po prostu konwertuje odczytany tekst na cyfry i zapisuje do zmiennej nr_tel.

mam nadzieję, że pomogłem, jeśli nadal nie rozumiesz, napisz mi w komentarzu dokładnie o problemie :)
komentarz 28 maja 2015 przez tarnasm Gaduła (3,030 p.)
Je się też wtrące. Jeśli dobrze rozumiem to program przykładowo do zmiennej 'imie' przypisze wartość na początku z lini 1 a potem co trzeciej linii?
komentarz 28 maja 2015 przez MrWeb Stary wyjadacz (10,180 p.)
Zauważ, że każda instrukcja case jest zakończona słowem break; to oznacza, że jeśli program analizuje tylko jedną linię z tych trzech case'ów w jednej iteracji pętli.

Kod wykonywany jest w ten sposób:

dopóki(jest jakaś linia do odczytania)

    przełącz_działania_dla_zmiennej(nr_linii)

        przypadek_gdzie_nr_linii==1 {  odczytaną linię wpisz do zmiennej imie }

        przypadek_gdzie_nr_linii==2 {  odczytaną linię wpisz do zmiennej nazwisko }

        przypadek_gdzie_nr_linii==3 { odczytaną linię wpisz do zmiennej nr_telefonu }

    zwiększ zmienną nr_linii o 1 (to już wykonuje się niezależnie od instrukcji switch!)
komentarz 28 maja 2015 przez Wiktor Stary wyjadacz (11,120 p.)

Dziękuję Tobie bardzo. A jeśli już tutaj piszemy to mam jeszcze jeden problem. Dokładnie chodzi o ciąg Fibonnaciego:

int n;
int fib[100000];

int main()
{
   cout<<"Ile liczb Fibonacciego wyznaczyc: ";
    cin>>n;

    fib[0]=1;
    fib[1]=1;

    for(int i=2;i<n;i++)
    {
        fib[i]=fib[i-1]+fib[i-2];

    }


    cout<<setprecision(10000);

    cout<<endl<<"Wyraz numer "<<n<<":"<<fib[n-1];

Dlaczego w tym kodzie (ostatnia linijka) musi występować zapis fib[n-1], a jak wstawie samo fib[n] to program zawsze pokaże mi 0.

komentarz 28 maja 2015 przez MrWeb Stary wyjadacz (10,180 p.)

tablice indeksuje się od 0 :)

int fib[100000] tworzy sto tysięcy intów ale indeksy tych komórek są od 0 do 99999

 

Spójrz na pętlę w 12 linijce, ona wykonuje się od i = 2 do i = n - 1

bo jest warunek i < n  (i mniejsze niż n, czyli że gdy i będzie równe zmiennej n to pętla się przerwie. To ważne, bo indeksowanie jest od zera)

a teraz co się dzieje w ostatniej linijce, wypisujesz liczbę n co jest poprawne, ale niepoprawne jest odwoływanie się do komórki z tablicy fib[]

Ta tablica jest duża (100 000 elementów) więc nie wystąpił żaden błąd, ale po prostu wyświetliłeś nie tą komórkę co trzeba, dlatego pokazywało Ci 0 :)

Pętla wpisuje wynik do ostatniej komórki która ma indeks fib[n - 1] a ty wyświetlasz fib[n]

 Ten błąd mógłby być gorszy gdybyś tworzył tablicę dynamiczną, bo wystąpiłby błąd off-by-one.

 

I przy okazji ciekawostka, dlaczego pokazało się 0 ?

Bo tablicę stworzyłeś globalnie, a wszystkie zmienne globalne są automatycznie zerowane ;)

komentarz 28 maja 2015 przez Wiktor Stary wyjadacz (11,120 p.)

Dziękuje Tobie bardzo. Właśnie testowałem fib[n-2] i działało normalnie tylko pokazywało poprzednią wartość niż wskazaną. I pięknie wkomponowała się tutaj Twoja ciekawostka o zerowaniu. :)

Pozdrawiam i dziękuję bardzo. smiley

+1 głos
odpowiedź 28 maja 2015 przez Eryk Andrzejewski Mędrzec (164,260 p.)
Switch - czyli przełącz. Polecenie przechodzi do odpowiedniego trybu, zależnie od wartości, którą pobiera. Czyli w tym przypadku switch przechwytuje zmienną nr_linii i zależnie od jej wartości(co ma zrobić dajemy w case) wykonuje odpowiednie polecenia. Jeśli nr_linii jest równy 1,to wykonują się polecenia z "case 1:". A jeśli nr_linii wynosi 3, to wykonuje się to, co jest w "case 3:". Pozdrawiam :)
+1 głos
odpowiedź 28 maja 2015 przez Piotr Królak Obywatel (1,950 p.)
#include <iostream>
#include <fstream>
#include <cstdlib>
 
using namespace std;
 
string imie, nazwisko;
int nr_tel;
 
int main()
{
system("color 1f"); 
system("chcp 1250>nul");
 
 /*Przyjmuję że wszystko co powyżej jest jasne i idę prosto do zagadnień związanych z wczytywaniem pliku*/
 
    fstream plik; //tworzysz zmienna plik
    plik.open("wizytowka.txt",ios::in); //tą zmienną plik otwierasz, w nawiasie jest podana nazwa pliku tekstowego wczytywanego pliku, ios::in oznacza że właśnie wczytujesz a bardziej dosłownie kierunek przepływu strumienia wejścia wyjścia(input output stream :: in)
 
    if(plik.good()==false) // tym ifem sprawdzasz czy ten plik istniej.
    {
        cout<<"Plik nie istnieje!"; //jeżeli nie istnieje to program się zakończy
        exit(0);
    }
 
 
    string odczytany_tekst; 
    int nr_linii=1;
 
    while(getline(plik, odczytany_tekst)) //pętla w której będzie się wypisywał tekst od lini 0, czy tam pierwszej
    {
        switch(nr_linii) //jak wyżej napisałem tekst pobiera się od początku, jeżeli wykryje linie 1 to wczytuje przypadek 1(case 1) itd.
    {
        case 1: imie = odczytany_tekst; break;
        case 2: nazwisko = odczytany_tekst; break;
        case 3: nr_tel = atoi(odczytany_tekst.c_str()); break;
    }
 
    nr_linii++; // inkrementacja numeru lini to chyba jasne ;)
}
 
 
cout<<imie<<endl;
cout<<nazwisko<<endl;
cout<<nr_tel<<endl;
 
 
 
plik.close(); //zamykasz plik, TO BARDZO WAŻNY KROK NIE WOLNO O TYM ZAPOMINAĆ !!!
 
system("PAUSE>nul"); 
return 0;
}

 

Podobne pytania

0 głosów
3 odpowiedzi 321 wizyt
0 głosów
2 odpowiedzi 636 wizyt
0 głosów
0 odpowiedzi 952 wizyt
pytanie zadane 15 kwietnia 2017 w Java przez plkpiotr Stary wyjadacz (12,420 p.)

93,715 zapytań

142,629 odpowiedzi

323,260 komentarzy

63,257 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.

...