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

PROBLEM: Odczyt z pliku tekstowego

Object Storage Arubacloud
0 głosów
380 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,200 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,200 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,200 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 173 wizyt
0 głosów
2 odpowiedzi 443 wizyt
0 głosów
0 odpowiedzi 691 wizyt
pytanie zadane 15 kwietnia 2017 w Java przez plkpiotr Stary wyjadacz (12,420 p.)

92,576 zapytań

141,426 odpowiedzi

319,652 komentarzy

61,961 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!

...