Zliczanie liter słowa – jak to powinno wyglądać?

2018-12-08 21:19
0

Witam, chcę napisać program zliczający ilość wystąpień kazdej litery słowa wczytanego wcześniej do tablicy. program powinien się opierać na funkcjach getchar i putchar. Czy coś takiego ma sens, czy inaczej to powinno być?

#include <stdio.h>
#define R 20
int main()
{
    int white = 0, other = 0;
    char nazwa[R] = { 'a' };
    int ilosc_znakow[R];
    int i = 0;
    printf("Maksymalna dlugosc nazwy to: %d\n ", R);
    while (i < R && nazwa[i] != EOF) {
        nazwa[i] = getchar();
        i++;
    }
    i = 0;
    while (i < R && nazwa[i] != EOF) {
        putchar(nazwa[i]);
        i++;
    }
    //for(int i=0;i<strlen(nazwa);i++)
    i = 0;
    while ((nazwa[i] = getchar()) != EOF) {
        if (nazwa[i] >= 'a' && nazwa[i] <= 'z') {
            ilosc_znakow[nazwa[i] - 'a']++;
        }
        else if (nazwa[i] == ' ' || nazwa[i] == '\n' || nazwa[i] == '\t') {
            white++;
        }
        else {
            other++;
        }
        i++;
    }
    for (char i = 'a'; i < 'z'; i++) {
        printf("%c : %d\n", i, ilosc_znakow[i]);
    }
    printf("Znaki biales: %d, znaki inne: %d", white, other);
    return 0;
}
edytowany 4x, ostatnio: furious programming, 2018-12-08 21:33
Pokaż pozostałe 2 komentarze
Chodzi o nastawienie używanego języka, nie generycznego znacznika code. Masz tam na prawo taką rozwijaną listę, wybierz z niej C. - MasterBLB 2018-12-08 21:29
W wcięcia brakuje zaczynając od wykomentowanego for :] - MasterBLB 2018-12-08 21:29
Szczerze mówiąc, widziałem gorzej, szczególnie od samej autorki. @Kamila Nowak: Nie znaczy to, że nie można lepiej ;​) Wcięcia są, ale są nierówno, dodatkowo nie ma kolorowania składni. Może na przyszłość przepuszczaj swój kod przez http://format.krzaq.cc przed wrzuceniem na forum. Ponadto, staraj się kolorować składnię (zamiast pierwszego ``` użyj ```c lub ```cpp, zależnie od użytego języka) - kq 2018-12-08 21:30
@kq: i znowu propagujesz herezję, eh... - MasterBLB 2018-12-08 21:35

Pozostało 580 znaków

2018-12-08 21:26
1

Dwa błędy na dzień dobry w pętli while:

  • masz getchar zamiast getchar()
  • z poprzedniej lekcji zapomniałaś, że są problemy z przesłaniem EOF do stdin z konsoli, i lepiej nie używać takiego warunku przerwania pętli.

"Sugeruję wyobrazić sobie Słońce widziane z orbity Merkurego, a następnie dupę tej wielkości. W takiej właśnie dupie specjalista ma teksty o wspaniałej atmosferze, pracy pełnej wyzwań i tworzeniu innowacyjnych rozwiązań. Pracuje się po to, żeby zarabiać, a z resztą specjalista sobie poradzi we własnym zakresie, nawet jeśli firma mieści się w okopie na granicy obu Korei."
-somekind,
konkretny człowiek-konkretny przekaz :]

Pozostało 580 znaków

2018-12-08 21:31
0

Bardzo dobry kod, ale potrzeba kilka poprawek:
1) 'R' proponuję zamienić na coś bardziej znaczącego, np. WORD_MAX_LEN

2) kod

int ilosc_znakow[R];

zamień na:

int ilosc_znakow['z' - 'a' + 1];

3) kod:

printf("%c : %d\n",i,ilosc_znakow[i]);

zamień na:

printf("%c : %d\n",i,ilosc_znakow[i - 'a']);

4) przetestuj na kilku słowach


Szacuje się, że w Polsce brakuje 50 tys. programistów

Pozostało 580 znaków

2018-12-08 21:33

Kolejny drobny błąd - nie inicjujesz tablicy int iloscZnakow[R] zerami, przez co fałszuje Ci wyniki.


"Sugeruję wyobrazić sobie Słońce widziane z orbity Merkurego, a następnie dupę tej wielkości. W takiej właśnie dupie specjalista ma teksty o wspaniałej atmosferze, pracy pełnej wyzwań i tworzeniu innowacyjnych rozwiązań. Pracuje się po to, żeby zarabiać, a z resztą specjalista sobie poradzi we własnym zakresie, nawet jeśli firma mieści się w okopie na granicy obu Korei."
-somekind,
konkretny człowiek-konkretny przekaz :]
Rozumiem, ale jak wyzerować tablice charów? - Kamila Nowak 2018-12-08 21:34

Pozostało 580 znaków

2018-12-08 21:37
1

Bardzo prosto Kamilka, definiujesz ją tak:

int iloscZnakow[R] = { 0 };

"Sugeruję wyobrazić sobie Słońce widziane z orbity Merkurego, a następnie dupę tej wielkości. W takiej właśnie dupie specjalista ma teksty o wspaniałej atmosferze, pracy pełnej wyzwań i tworzeniu innowacyjnych rozwiązań. Pracuje się po to, żeby zarabiać, a z resztą specjalista sobie poradzi we własnym zakresie, nawet jeśli firma mieści się w okopie na granicy obu Korei."
-somekind,
konkretny człowiek-konkretny przekaz :]
edytowany 1x, ostatnio: MasterBLB, 2018-12-08 21:37
Tak, teraz widzę, po prostu mi się trochę pomieszało z tym co kolega wyżej napisał, aby zamienić R na inny zapis. - Kamila Nowak 2018-12-08 21:37

Pozostało 580 znaków

2018-12-08 21:40
0

Poprawione. Jednak program dalej zatrzymuje się na wczytaniu i wypisaniu wyrazu.

Pokaż kod, bo inaczej możemy jedynie wyrazić ubolewanie. - vpiotr 2018-12-08 21:41

Pozostało 580 znaków

2018-12-08 21:55
0

Zamień:

while((nazwa[i]=getchar())!=EOF)

na:

while(nazwa[i])

Szacuje się, że w Polsce brakuje 50 tys. programistów
Niestety, nie pomogło. Może to jednak problem z zapisem ilosc_znakow[nazwa[i]-'a']++ ? - Kamila Nowak 2018-12-08 22:03
Dziwne, u mnie działa. Jeszcze jedna poprawka: zamień while (i < R && nazwa[i] != EOF) { na while (nazwa[i]) { - vpiotr 2018-12-08 22:05
Mógłbyś udostępnić mi ten działający kod? Bo u mnie niestety jak wyżej, nie wychodzi. - Kamila Nowak 2018-12-08 22:15

Pozostało 580 znaków

2018-12-08 22:21
0
#include <stdio.h>
#define R 20
int main()
{
    int white = 0, other = 0;
    char nazwa[R] = { 'a', '\0' };
    int ilosc_znakow['z' - 'a' + 1] = { 0 };
    int i = 0;
    int c = 0;
    printf("Maksymalna dlugosc nazwy to: %d\n ", R);
    while (i < R) {
        c = getchar();
        if (c == EOF)
            break;
        nazwa[i] = c;
        i++;
    }
    i = 0;
    while (nazwa[i]) {
        putchar(nazwa[i]);
        i++;
    }
    //for(int i=0;i<strlen(nazwa);i++)
    i = 0;
    while (nazwa[i]) {
        if (nazwa[i] >= 'a' && nazwa[i] <= 'z') {
            ilosc_znakow[nazwa[i] - 'a']++;
        }
        else if (nazwa[i] == ' ' || nazwa[i] == '\n' || nazwa[i] == '\t') {
            white++;
        }
        else {
            other++;
        }
        i++;
    }
    for (char i = 'a'; i < 'z'; i++) {
        printf("%c : %d\n", i, ilosc_znakow[i - 'a']);
    }
    printf("Znaki biales: %d, znaki inne: %d", white, other);
    return 0;
}

Poprawiłem na tyle żeby działało bez krzaków na ekranie.


Szacuje się, że w Polsce brakuje 50 tys. programistów
Nie wiem, ale u mnie nie wypisuje w ogóle wystąpień żadnej litery, tylko kończy się na putchar - Kamila Nowak 2018-12-08 22:26
Ten program działa ze słowem "test". Dla innych może mieć jeszcze kilka błędów. - vpiotr 2018-12-09 06:37

Pozostało 580 znaków

2018-12-09 00:34
2
Kamila Nowak napisał(a):

Witam, chcę napisać program zliczający ilość wystąpień kazdej litery słowa wczytanego wcześniej do tablicy. program powinien się opierać na funkcjach getchar i putchar. Czy coś takiego ma sens, czy inaczej to powinno być?

Cześć. Kiedyś napisałem podobny program, tylko że zlicza same, konkretne litery, bez spacji czy innych znaków, ale łatwo to zmodyfikować korzystając z gotowych funkcji obsługi znaków z pliku cctype, takich jak np. isspace() itd. Możesz sobie porównać.

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

int main()
{
   int f = 0; int i=0; int i2=0;
   char ch;

   char const alf[] = "abcdefghijklmnopqrstuvwxyz";
   int wynik[26] = {[25] = 0}; //jeżeli do jednego elementu przypiszemy zero, to reszta elementow automatycznie otrzymuje zera

   printf("Wpisz jakies slowo, a ja wypisze, ile razy wystepuje dana litera\n");
   printf("Wpisz slowo: \n");

   while( (ch = getchar()) != '\n')
   {
       while(f<1)
       {
        if(i==26)
          break;

        if(ch == alf[i])
        {
           i2++;
           wynik[i]++;
           f=1;
        } i++;

       } f=0; i=0;
   } i=0;

   printf("\nPodane slowo ma %d liter\n", i2);
   printf("\nZawiera nastepujace litery:\n");

   while(i<26)
   {
       if(wynik[i] == 0)
       {
           i++;
           continue;
       }

       printf("Litera %c wystepuje %d razy\n", alf[i], wynik[i]);
       i++;
   }
   getchar();

    return 0;
}
edytowany 2x, ostatnio: kario97, 2018-12-09 12:37
Super, mam pytanie: Czym jest zmienna f w całym programie? - Kamila Nowak 2018-12-12 21:39
odpowiedziałem w osobnym poście - kario97 2018-12-12 22:21

Pozostało 580 znaków

2018-12-12 22:21
1

W programowaniu na taką zmienną mówi się zmienna flagowa lub flaga. Można powiedzieć, że flaga to zmienna, która po otrzymaniu konkretnej wartości, pozwoli komputerowi przejść do konkretnej części programu (najczęściej są to wartości true lub false czyli 1 lub 0). Nie wiem, czy dobrze zdefiniowałem co to jest flaga, jeżeli masz jakieś wątpliwości, co to jest w ogóle flaga w programowaniu, to poczytaj o tym na necie, a teraz wytłumaczę, co konkretnie robi ta zmienna w tym programie:
W tym przypadku zmienna f jest potrzebna do pętli while(f<1), czyli pętla ma się wykonywać tak długo, dopóki prawdą jest, że zmienna f jest mniejsza od 1. Domyślnie ta zmienna jest ustawiona na 0, czyli program przechodzi do tej pętli i wykonuje tam wszystkie czynności. W tej pętli chodzi o to, żeby sprawdzać po kolei zawartość tablicy alf z pobranym znakiem w zmiennej ch - jeżeli litera w zmiennej ch równa się którejś wartości z tablicy alf[], to wartość zmiennej wynik[] jest zwiększana o 1 (myślę, że rozumiesz algorytm tego programu? zresztą widać to po działaniu programu i po tym, co wypisuje ostatnia pętla), a następnie flaga otrzymuje wartość 1. Wtedy program ponownie przechodzi do warunku pętli i tym razem warunek pętli jest już fałszywy, gdyż zmienna f=1, a powinna być <1, żeby pętla się dalej wykonywała. Ponieważ warunek pętli jest fałszywy, program wychodzi z niej, z powrotem ustawia flage na 0 i wraca do pętli głównej while( (ch = getchar()) != '\n'), żeby pobrać kolejny znak i powtórzyć wszystkie czynności, aż dojdzie do znaku nowej linii.

Super. Dziękuję. Daloby się jakoś ominąć tą flagę i zapisać warunek w inny sposób? - Kamila Nowak 2018-12-12 22:26

Pozostało 580 znaków

2018-12-12 22:31
1

Można takie coś xD:

while( (ch = getchar()) != '\n')
   {
       while(1)
       {
        if(i==26)
          break;

        if(ch == alf[i])
        {
           i2++;
           wynik[i]++;
           i++;
           break;
        }

       } f=0; i=0;
   } i=0;

Wiesz na jakiej zasadzie teraz to działa? ;)
A co, nie podoba Ci się sama idea stosowania flagi jako warunku w pętli/instrukcji if? Moim zdaniem jest to bardzo przydatne, czasami lepiej podać pojedynczą zmienną, niż jakieś dłuższe wyrażenie logiczne.

edytowany 1x, ostatnio: kario97, 2018-12-12 22:33
Już wzystko jasne. Dziekuje ;) - Kamila Nowak 2018-12-12 22:35
Czyli na dobrą sprawę można by bylo to zinterpretować jako while(znaleziono==false) i następnie w funkcji zamieniamy znaleziono=true; i znowu po funkcji znaleziono==false. - Kamila Nowak 2018-12-12 22:45
odpowiedziałem niżej, tego typu dyskusje raczej prowadzi się w postach :P - kario97 2018-12-12 22:52

Pozostało 580 znaków

Liczba odpowiedzi na stronę

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0