• 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

VPS Starter Arubacloud
0 głosów
342 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,290 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 296 wizyt
pytanie zadane 29 września 2018 w C i C++ przez Shimeo7 Obywatel (1,910 p.)
0 głosów
1 odpowiedź 257 wizyt
pytanie zadane 18 maja 2016 w C i C++ przez Tommy Użytkownik (520 p.)
0 głosów
1 odpowiedź 317 wizyt

92,453 zapytań

141,262 odpowiedzi

319,088 komentarzy

61,854 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

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 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!

...