Cześć wszystkim!
Dopiero zaczynam swoją przygodę z C. Aktualnie przerabiam książkę "Język C Szkoła programowania" S. Prata.
Wszystkie ćwiczenia, które wykonuję, staram się robić w miarę możliwości samodzielnie. Jeśli coś mi nie idzie, wałkuję jeden rozdział aż go dobrze zrozumiem. Mimo wszystko od pewnego czasu trafiłem na blokadę, której w żaden sposób nie mogę sforsować.
Zatrzymałem się na ćwiczeniu nr 1 z 8. rozdziału powyższej książki "Znakowe wejście-wyjście i przekierowywanie".
Treść ćwiczenia jest następująca: "Napisz program, który zlicza znaki (wpisywane lub pobierane z pliku) aż do wystąpienia końca pliku".
Nie chcąc iść na łatwiznę, próbuję napisać program, w którym to od użytkownika będzie zależało, czy będzie zliczał znaki z pliku, czy z klawiatury.
O ile zliczając znaki z pliku, wszystko jest tak jak być powinno, problem jest przy zliczaniu znaków z klawiatury.
Program liczy znaki wpisane przez użytkownika prawidłowo. Po wpisaniu swojego tekstu, na koniec w nowym wierszu wprowadzając EOF (ctrl+Z), następuje nieskończona pętla, tak jakby (jeśli dobrze zrozumiałem zagadnienie) EOF zostaje w buforze wejściowym, którego w żaden sposób nie potrafię opróżnić.
Oto mój kod:
// Ćwiczenie_1.c -- program zlicza znaki z pliku lub wpisane z klawiatury, zaleznie od wybranej przez uzytkownika opcji
#include <stdio.h>
#include <stdlib.h>
int zliczanie_program(void); // funkcje zwroca wartosc typu int, i nie pobiora z funkcji main zadnego argumentu,
int zliczanie_plik(void); // dane do wykonania tych funkcji beda rowniez w nich pobierane
char zla_opcja(int wpisana_opcja); // gdy uzytkownik wpisze inny znak, niz 'a', 'b' lub 'q'
int main(void)
{
int opcja;
printf("Program policzy ilosc znakow wpisanych przez uzytkownika\n");
printf("do programu lub do pliku tekstowego, zaleznie od wybranej opcji.\n\n");
printf("Wybierz opcje:\n");
printf("a) zliczanie znakow wpisanych w programie,\n");
printf("b) zliczanie znakow wpisanych do pliku txt,\n");
printf("q) zakoncz program.\n");
while((opcja = getchar()) != 'q')
{
switch(opcja)
{
case 'a': zliczanie_program();
break;
case 'b': zliczanie_plik();
break;
case EOF: printf("Przechodzi przez switch w funkcji main\n");
printf("opcja = %d\n\n", opcja); // EOF powoduje nieskonczona petle
//break;
default: zla_opcja(opcja);
}
printf("Wybierz opcje:\n");
printf("a) zliczanie znakow wpisanych w programie,\n");
printf("b) zliczanie znakow wpisanych do pliku txt,\n");
printf("q) zakoncz program.\n");
fflush(stdin); // czyści bufor wejściowy z EOF po wyjściu z pliku txt
}
printf("Koniec programu!\n\n");
return 0;
}
int zliczanie_program(void)
{
int znak;
int ilosc_drukowanych = 0;
int ilosc_niedrukowanych = 0;
int ilosc_znakow = 0;
printf("Wybrales opcje zliczania znakow wpisanych do programu.\n");
printf("Wpisz ponizej dowolny tekst, a program policzy ilosc wpisanych znakow.\n");
while((znak = getchar()) != '\n'); //jesli wczesniej zatwierdzono enterem opcje a, bez tego polecenia wypisze pierwszy case ze switcha
while((znak = getchar()) != EOF)
{
if((znak == '\n') || (znak == '\t') || (znak == ' '))
{
switch(znak)
{
case '\n': ilosc_niedrukowanych++;
printf("wpisano znak: '\\n', ilosc niedrukowanych: %d\n", ilosc_niedrukowanych); // -> // wyswietla jeden /
break;
case '\t': ilosc_niedrukowanych++;
printf("wpisano znak: tab, ilosc niedrukowanych: %d\n", ilosc_niedrukowanych);
break;
case ' ': ilosc_niedrukowanych++;
printf("wpisano znak: spacja, ilosc niedrukowanych: %d\n", ilosc_niedrukowanych);
break;
}
}
else
{
ilosc_drukowanych++;
printf("wpisano znak: %c, ilosc drukowanych: %d\n", znak, ilosc_drukowanych);
}
}
ilosc_znakow = ilosc_drukowanych + ilosc_niedrukowanych;
printf("\n");
printf("Wprowadzono %d znakow, z czego:\n", ilosc_znakow);
printf("- %d znakow drukowanych,\n", ilosc_drukowanych);
printf("- %d znakow niedrukowanych.\n\n", ilosc_niedrukowanych);
return 0;
}
int zliczanie_plik(void)
{
int ilosc_drukowanych = 0;
int ilosc_niedrukowanych = 0;
int ilosc_znakow = 0;
int znak_plik;
FILE * fp;
fp = fopen("plik_do_odczytu.txt", "r");
if(fp == NULL)
{
printf("Blad przy probie otwarcia pliku.\n");
exit(1);
}
printf("Do pliku tekstowego wpisano tekst:\n");
while((znak_plik = getc(fp)) != EOF)
{
putchar(znak_plik);
if((znak_plik == '\n') || (znak_plik == '\t') || (znak_plik == ' '))
ilosc_niedrukowanych++;
else
ilosc_drukowanych++;
}
ilosc_znakow = ilosc_drukowanych + ilosc_niedrukowanych;
printf("\n\n");
printf("W pliku tekstowym naliczono %d znakow, z czego:\n", ilosc_znakow);
printf("- %d znakow drukowanych,\n", ilosc_drukowanych);
printf("- %d znakow niedrukowanych.\n\n", ilosc_niedrukowanych);
fclose(fp);
return 0;
}
char zla_opcja(int wpisana_opcja)
{
printf("Wpisano %d.\n", wpisana_opcja); // %d wypisze kod znaku z ASCII, %c wypisze znak
printf("Nalezy wpisac a, b lub q.\n\n");
return 0;
}
Próbowałem już wielu rzeczy, łącznie z funkcją 'fflush(stdin)', której teoretycznie nie chciałem używać w tym programie, ponieważ jeszcze nie doszedłem do niej w książce. Program starałem się napisać sam, tyle, że siedzę nad nim już od jakiegoś miesiąca i powoli ręce opadają.
Będę wdzięczny za wszelką pomoc.
Dzięki!
Olav93