Šta je novo?

Pomoc oko c kod-a

sportsdirect

Cenjen
Učlanjen(a)
18.11.2013
Poruke
36
Poena
159
Treba mi pomoc oko objasnjenja sledeceg koda:

while (getchar() != 'y') /* get response, compare to y */
{
printf("Well, then, is it %d?\n", ++guess);
while (getchar() != '\n')
continue; /* skip rest of input line */
}


koliko razumem getchar cita karakter po karakter, pa me zanima kako ovaj kod odbacuje enter (\n) tj kad otkucam odgovor N pa lupim enter zar ne bi trebao dva puta da mi prikaze printf tj zar ne bi trebao getchar da oba karaktera pusti kroz petlju od pocetka?
 
On pročita prvi karakter i ako je različit od 'y' ispisuje uvećanu vrednost guess i projuri do kraja reda i opet jovo nanovo sve dok ne naleti na 'y'..
 
Tebe verovatno buni kako rade buffer i getchar().

1. Otvori ti se konzola, ti upišeš neke karaktere i pritisneš enter, u tom momentu bafer se napuni tim karakterima uključujući i enter.

2. Svaki put kad u kodu pozoveš getchar() on uzima karakter iz bafera.

Ako pokreneš ovaj kod:

Kod:
int  main(){

    char a;

    a = getchar();
    printf("\nPrvi karakter uzet iz bafera, ascii vrednost je: %d, a karakter je: '%c'",a,a);
    a = getchar();
    printf("\nDrugi karakter uzet iz bafera, ascii vrednost je: %d, a karakter je: '%c:'",a,a);
    a = getchar();
    printf("\nTreci karakter uzet iz bafera, ascii vrednost je: %d, a karakter je: '%c:'",a,a);
    return 0;
}

a) kao input u konzoli upišeš abc i prtisneš enter on će uzeti iz buffera a, b i c i ispisati sve tri poruke
b) kao input u konzoli upišeš ab i prtisneš enter on će uzeti iz buffera a, b i ENTER (videćeš da je treća poruka presečena između navaodnika) i ispisati sve tri poruke
c) kao input u konzoli upišeš a i pritisneš enter on će uzeri iz buffera a i ENTER i ispisati prve dve poruke, a onda u konzoli zatražiti da uneseš još karaktera jer je bafer prazan, u sebi je imao dva karaktera, a ti si pozvao getchar() tri puta i getchar() nema više šta da iščita.

S obzirom na sve ovo gore napisano, zašto tvoj kod ne ispisuje enter.

1. Proverava se uslov spoljne while petlje tako što se uzme prvi karakter iz bafera, ako nije y ulaziš u telo petlje
2. Ušao si u petlju, ispisuje se printf(), proverava se uslov unutrašnje petlje tako što se uzima sledeći karakter iz bafera. Koja je svrha ove unutrašnje petlje? Njen uslov uzima karaktere iz bafera sve dok ne uzme i enter i na taj način prazni bafer. Zato ti nigde ne vidiš ENTER.

Pokreni ovaj modifikovani kod, mislim da će ti tako biti najjasnije:

Kod:
int  main(){

    char a;

    while ((a=getchar()) != 'y') {
        printf("\nSpoljna petlja -> Iz bafera uzet karakter cija je ASCII vrednost: %d", a);
        while (a=getchar()){
            printf("\nUnutrasnja petlja -> Iz bafera uzet karakter cija je ASCII vrednost: %d", a);

            if (a == '\n'){
                printf("\nOk, to je enter, bafer je prazan i izlazimo iz unutrasnje petlje\n");
                break;
            }
        }
    }
    return 0;
}
 
Poslednja izmena:
Hvala ti puno na objasnjenju, ja sam se zbunio oko unutrasnje petlje jer sam mislio da ce izaci cim se ispuni uslov pa ponovo pokrenuti prvi while, ustvari izvrsava se sve dok nema \n , znao sam za buffer da ceka dok ne pritisnem enter pa onda salje, sad verovatno nisam stigao do te lekcije u knjizi ali mislim da ima i funkcija za unbuffered input. Hvala vam jos jednom puno 🙂
 
Ajde jos nesto da te pitam 🙂

imam sledeci kod

char get_choice(void)
{
int ch;
printf("Enter the letter of your choice:\n");
printf("a. advice b. bell\n");
printf("c. count q. quit\n");
ch = get_first();
while ( (ch < 'a' || ch > 'c') && ch != 'q')
{
printf("Please respond with a, b, c, or q.\n");
ch = get_first();
}
return ch;
}


char get_first(void)
{
int ch;
ch = getchar();
while (getchar() != '\n')
continue;
return ch;
}


Funkcija char get_first(void) cisti buffer

da li ja mogu da odradim bez druge funkcije isto tj da spakujem sve u prvu, na primer :

char get_choice(void)
{
int ch;
printf("Enter the letter of your choice:\n");
printf("a. advice b. bell\n");
printf("c. count q. quit\n");
ch = getchar();
while ( (ch < 'a' || ch > 'c') && ch != 'q')
{
printf("Please respond with a, b, c, or q.\n");
while ((ch = getchar())!='\n');
continue;
}
return ch;
}
 
da li ja mogu da odradim bez druge funkcije isto tj da spakujem sve u prvu

Možeš da integrišeš get_first(void) u get_choice(void), izdvojena je da bi kod bio čistiji, jer se poziva na više mesta. Samo kod za čišćenje bafera dodaj odmah ispod prvog getchar() i popravi kod u drugom while-u jer će promenljivoj ch uvek biti dodeljena vrednost '\n', jer se uslov u petlji proverava sve dok vrednost ch ne postane enter.

Ne znam šta pokušavaš da uradiš, ali u principu ne bi trebalo da spajaš funkcije, jer je ovako kako je napisano dobra praksa.

Inače kad petlju napišeš kao while(1); znači sa ';' na kraju, ne moraš da koristiš continue.
 
Znaci da je uvek bolje razdvajati funkcije zbog lakseg citanja i kasnijeg nalazenja istog? Inace citam knjigu od Stephen Prata C 5th edition to su primeri iz njegovih knjiga. Znam da continue; i samo ; nego sam skorije to radio pa samo zbog toga to pise ali izbacicu. Prve dve funkcije su primer iz njegove knjige char get_choice(void) i char get_first(void) a ja sam hteo da probam cisto radi eksperimenta da to sve spakujem u jednu funkciju. Kada si mi rekao da "popravi kod u drugom while-u jer će promenljivoj ch uvek biti dodeljena vrednost '\n'," da li si mislio na while ((ch = getchar())!='\n'); u zadnjoj funkciji ?
 
Znaci da je uvek bolje razdvajati funkcije zbog lakseg citanja i kasnijeg nalazenja istog? Inace citam knjigu od Stephen Prata C 5th edition to su primeri iz njegovih knjiga. Znam da continue; i samo ; nego sam skorije to radio pa samo zbog toga to pise ali izbacicu. Prve dve funkcije su primer iz njegove knjige char get_choice(void) i char get_first(void) a ja sam hteo da probam cisto radi eksperimenta da to sve spakujem u jednu funkciju. Kada si mi rekao da "popravi kod u drugom while-u jer će promenljivoj ch uvek biti dodeljena vrednost '\n'," da li si mislio na while ((ch = getchar())!='\n'); u zadnjoj funkciji da li treba da bude samo while (getchar() != '\n') bez varijable?
 
Znaci da je uvek bolje razdvajati funkcije zbog lakseg citanja i kasnijeg nalazenja istog?

Prvo lakše je pratiti kod, drugo kad jedna funkcija radi samo jednu stvar lakše je i debagovati. Napišeš funkciju, istestiraš je i siguran si kasnije gde god da je u kodu iskoristiš da ona nije problem. Takva organizacija koda će ti dosta pomoći kasnije kad budeš pisao veće aplikacije.

Kada si mi rekao da "popravi kod u drugom while-u jer će promenljivoj ch uvek biti dodeljena vrednost '\n'," da li si mislio na while ((ch = getchar())!='\n'); u zadnjoj funkciji da li treba da bude samo while (getchar() != '\n') bez varijable?

Ne, u tom slučaju ch nikad ne bi dobio novu vrednost i spoljna petlja bi ti se vrtela večno.

Moraš ovaj deo koda

Kod:
ch = getchar();
while (getchar() != '\n')

imati i pre glavne petlje i u njoj.

Kod:
char get_choice(void)
{
int ch;
printf("Enter the letter of your choice:\n");
printf("a. advice b. bell\n");
printf("c. count q. quit\n");
ch = getchar();
while (getchar() != '\n');
while ( (ch < 'a' || ch > 'c') && ch != 'q')
{
printf("Please respond with a, b, c, or q.\n");
ch = getchar();
while (getchar() != '\n');
}
return ch;
}
 
Hvala ti puno jos jednom na pomoci, shvatio sam. Mogu da ti kazem da odlicno objasnjavas , mogao bi knjigu da napises 🙂
 
Nazad
Vrh Dno