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

wyjaśnienie działania programu zliczającego słowa, znaki i wiersze w C

Aruba Cloud VPS - 50% taniej przez 3 miesiące!
0 głosów
394 wizyt
pytanie zadane 26 czerwca 2022 w C i C++ przez laf92 Nowicjusz (120 p.)

Cześć wszystkim!

Jestem na początku nauki języka C, obecnie przerabiam lekturę autorstwa Dennis'a M. RItchie i Briana W. Kernighana - mianowicie "Język ANSI C".

Poległem przy jednym z przykładów podanych przez autorów, jest to program służący do zliczania wpisywanych przez użytkownika słów, wierszy i znaków; kod zamieszczam poniżej.

 

#include <stdio.h>

#define IN 1  // wewnątrz słowa
#define OUT 0 // poza słowem

// zlicz wejściowe wiersze, słowa i znaki

main(){
int c, nl, nw, nc, state;

state = OUT;
nl = nw = nc = 0;
while((c = getchar())!=EOF){

++nc;
if(c == '\n')
++nl;
if(c == ' ' || c == '\n' || c == '\t')
state = OUT;
else if (state == OUT){
state = IN;
++nw;
   }
}
printf("%d%d%d\n", nl nw, nc);
}

Czy mógłbym prosić kogoś o poświęcenie trochę swojego czasu i  wytłumaczenie mi łopatologicznie czemu każdy poszczególny wers kodu ma służyć? O rozłożenie go na czynniki pierwsze? indecision

 

1 odpowiedź

+2 głosów
odpowiedź 26 czerwca 2022 przez Oscar Nałogowiec (29,340 p.)
edycja 26 czerwca 2022 przez Oscar
// Potrzebne będą funkcje do czytania i pisania
#include <stdio.h>
 
#define IN 1  // wewnątrz słowa
#define OUT 0 // poza słowem
 
// zlicz wejściowe wiersze, słowa i znaki
 
main(){

    // zmienne rozdzieliłem według ich roli w programie

    // aktualnie wczytany znak - wejscie to po prostu ciąg znaków
    int c;          
    // liczniki - odpowiednio linii, słów i znaków
    int nl, nw, nc;

    // Slowo to taki spójny podciąg składający się z 
    // widocznych znaków. By wykryć słowo trzeba 
    // znaleźć miejsce gdzie taki podciąg się 
    // zaczyna i kończy. Czyli gdy po znaku widocznym 
    // jest niewidoczny (koniec) lub odwrotnie (poczatek)
    // trzeba wiedziec czy aktualnie wczytawanie jest 
    // wewnątrz slowa czy nie.
    // Tak naprawdę jest to po prostu wiedza jaki 
    // znak poprzednio odczytano.

    int state;
 
    // zaczynany jakby będąc poza słowem
    state = OUT;

    // wszystkie 3 liczniki na zero
    nl = nw = nc = 0; 

    // najbardziej elementarna pętla wczytywania 
    // znaków do końca pliku
    // By zakończyć program trzeba 
    // "wygenerować" znak końca pliku 
    // (zależnie od systemu)
    while((c = getchar())!=EOF){

        // Każdy wczytany znak uaktualnia licznik znaków
        ++nc;

        // jeśli to koniec linii to uaktualnienie licznika linii
        if(c == '\n')
            ++nl;

        // spacja, tabulacja i nowa linia to 
        // znaki "niewidoczne", rozdzielające wyrazy
        if(c == ' ' || c == '\n' || c == '\t')
            // wczytanie takiego znaku -
            // czytamy poza słowem
            state = OUT;
        else if (state == OUT){
            // jesli znak jest "widoczny" a poprzedni był 
            // "niewidoczny" to mamy początek wyrazu
            // zapamietać że czytamy już "w środku wyrazu"
            state = IN;
            // odliczyć kolejny wyraz
            ++nw;
        }
    }
    // wypisać wynik
    printf("%d%d%d\n", nl nw, nc);
}

Takie trochę lepiej sformatowane i skomentowane źródło. Nie opisuje co robią poszczególne instrukcję języka C - od tego masz książkę (autorzy to twórcy języka C) a co robią konkretnie w tym programie, na czym polega ich rola w "liczeniu". Swoją drogą masz program będący uproszczoną wersją polecenia "wc" (bez skojarzeń) z Linuxa.

Program ma jedną wadę/cechę - jeśli w pliku nie będzie końca wiersza licznik linii będzie miał 0.

komentarz 26 czerwca 2022 przez laf92 Nowicjusz (120 p.)

Dzięki wielkie!

Świetnie objaśnione, teraz rozumiem. Wpisując znak rozdzielający dajemy znać komputerowi, że zaczyna się nowa linia i co za tym idzie - nowy ciąg znaków, czyli wyraz (o ile ta linia też nie zostanie przerwana znakiem rozdzielającym).

Wygląda na to że muszę bardziej popracować nad logicznym myśleniem :D

Jeszcze raz dzięki za wyjaśnienie i poświęcony czas, wracam do lektury! smiley

Podobne pytania

0 głosów
3 odpowiedzi 351 wizyt
pytanie zadane 29 września 2018 w C i C++ przez Shimeo7 Obywatel (1,910 p.)
0 głosów
1 odpowiedź 332 wizyt
pytanie zadane 18 maja 2016 w C i C++ przez Tommy Użytkownik (520 p.)
0 głosów
1 odpowiedź 539 wizyt

93,110 zapytań

142,091 odpowiedzi

321,614 komentarzy

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

Wprowadzenie do ITsec, tom 1 Wprowadzenie do ITsec, tom 2

Można już zamawiać dwa tomy książek o ITsec pt. "Wprowadzenie do bezpieczeństwa IT" - mamy dla Was kod: pasja (użyjcie go w koszyku), dzięki któremu uzyskamy aż 15% zniżki! Dziękujemy ekipie Sekuraka za fajny rabat dla naszej Społeczności!

...