[ VukSta @ 23.09.2006. 16:18 ] @
#include <stdio.h>

int c;

main()
{
c= getchar();
while (c != EOF)
{
putchar (c);
c = getchar ();
}


return 0;
}


Jednostavan zadatak iz Ricijeve knjige,ali nesto ne razumem.zasto mi ne dozvoljava da unos bude u dva ili vise redova,zasto odmah pri pritisku na ENTER,prestaje sa unosom i kopira to sto sam do tada uneo u izlaz?zar kraj programa ne bi trebalo da oznaci ctrl+z,a ne ENTER?
[ NrmMyth @ 23.09.2006. 16:38 ] @
Koji kompajler, meni na DevCpp 4.9 radi korektno.
[ djalfirevic @ 23.09.2006. 18:08 ] @
Citat:
VukSta: #include <stdio.h>

int c;

main()
{
c= getchar();
while (c != EOF)
{
putchar (c);
c = getchar ();
}


return 0;
}


Jednostavan zadatak iz Ricijeve knjige,ali nesto ne razumem.zasto mi ne dozvoljava da unos bude u dva ili vise redova,zasto odmah pri pritisku na ENTER,prestaje sa unosom i kopira to sto sam do tada uneo u izlaz?zar kraj programa ne bi trebalo da oznaci ctrl+z,a ne ENTER?


Mozda je negde kasnije u knjizi objasnjeno zasto. Mozda je Dennis Ritchie hteo da ENTER bude EOF!?
[ VukSta @ 23.09.2006. 18:55 ] @
Radim u Codeblocks -u.ne znam kako da pogledam koji mi je kompajler:(
@djalfirevic
ne verujem da je EOF=ENTER,sudeci po kasnijim primerima,u kojima je EOF ctrl+z.
[ Tiristor @ 24.09.2006. 05:55 ] @
probaj umesto inta da stavis char i posle u okviru while c stavi pod navodnicima.
[ toxi_programer @ 25.09.2006. 14:23 ] @

Ovako, komandom getchar() ucitavas neki niz u bafer stdio-a dok se vrednost prvog unetog elementa vraca(tip je int) i pozicija unutar bafer se postavlja na 2. znak po redu. dakle ako se unese "toxi", 't' ce biti vraceno a pozicija unutar bafera postavljena na znak 'o'. U bafer ce se smestiti svi znaci koje si otkucao pre ENTER tj.prelaska u novi red ali ce se u bafer smestiti i taj simbol za novi red( '\n' ). Dakle u pitanju je nacin baferovanja stdin-a, dakle on se baferuje u redove.
Kada se u while petlji dodje na f-ju getchar, za razliku od prvog puta program nece cekati da se nova vrednost unese dok se god u baferu nalaze znaci. Kada se oni svi prikazu (tj pozicija unutar bafera pokazuje na simbol '\0') uslov petlje je i dalje vazeci i zato ti program trazi da uneses novi tekst.


-Vidi, unesi "REC" i pritisni ctrl + z. Nista se nece desiti dok ne pritisnes enter. Onda ce se ispisati "REC", prelazi se u novi red i program se zatvara. Dakle tekst se programu "predaje" po pritisku na enter, to je ustaljeno ponasanje.
Kao slucija, mozes sve snimati u jednu promenljivu char[ 1000 ] pa po nailasku na EOF znak to sve prikazati.
[ Tiristor @ 25.09.2006. 21:44 ] @
Aha u tome je stvar. Ja sam uvek imao problema sa tim getcharom i u principu gledao sam da ga izbegavam. Dobar je kada treba da uneses neki niz sa belim znacima, ali kada sam ga koristio za unos 1 karaktera imao sam problema. Sve je u redu kad pretisnes 1 karakter, ali ako slucajno pritisnes vise on taj jedan dodeli promenjivoj, a ove ostale dodeljuje sledecem stringu koji treba da se unese. Najveci problem je bio sto dodeljuje i enter, pa kad imam getchar, a zatim i unos sa konverzijom %s on mi taj unos preskoci, jer na getchar unosi znak koji treba, a enter ostaje za sledeci string koga pokupi %s i prekine mi unos.
[ NrmMyth @ 26.09.2006. 09:48 ] @
sve je to tako jer je IO stream
[ VukSta @ 27.09.2006. 17:45 ] @
@toxi_programer
Hvala na pomoci!
[ toxi_programer @ 27.09.2006. 19:39 ] @
@VukSta
- Ovo mi je zapalo za oko jer sam i ja kada sam ucio C naisao na isti problem, pitao sam i niko da da konkretan odgovor svi kao "zaobidji getchar()..." idr...
-No ako koristis getchar za uzimanje samo jednog znaka od korisnika( tesko da ces doci u pomenutu situaciju ali valja znati) posle poziva getchar() pozovi f-ju fflush( neki_tok ) gde je neki_tok npr stdin ili koji vec hoces da "ispraznis".
[ VukSta @ 28.09.2006. 20:28 ] @
Imam jos jedno pitanje u vezi getchar.Mozda nisam dobro razumeo,pa me sada ovo buni.U onom primeru koji sam naveo,tekst se kopira odmah pri pritisku na ENTER,Enter daje znak da program pocne da se izvrsava.
Ali u drugom primeru,ENTER nije taj koji ce okoncati unos (kao u primeru gore),vec ctrl + z,kao sto bi i trebalo.
moje pitaje je: koja je sad razlika izmedju ova dva koda,odnosno zasto je u prvom primeru ENTER signal za izvrsetak programa,au drugom je to EOF?
evo koda:

#include <stdio.h>
main()
{
double i;


for(i=0; getchar()!=EOF; ++i);

printf("%.0f",i);


}

program broji znakove.

Hvala!
[ toxi_programer @ 29.09.2006. 14:03 ] @
Ne znam koji kompajler koristis ali u ovom primeru koji si naveo imas EOF, to je makro i ima vrednost -1. Ja kad u VS6 izvrsim ovaj kod, dal stisno il' ne stisko ctrl + z isto mi se vata, a ako izmenim program da na mestu EOF stoji '\n' sve radi kako treba tj. uneses jednom rec i dobijes broj slova a u onom tvom slucaju upisujes u nedogled.

-Da se malo ispravim, ako imas kompajler iz vremena dos-a, npr Turbo C, onda ce se tretman kraja fajla iz navedenog primera ispostovati, jer ti prevodioci navedenu komandu tako interpretiraju.

PS. Enter bi okoncavao unos ako stavis umesto EOF '\n' ( cisto da potvrdim jos jednom gore napisano)
pozz
[ VukSta @ 29.09.2006. 18:16 ] @
Citat:
toxi_programer:

PS. Enter bi okoncavao unos ako stavis umesto EOF '\n' ( cisto da potvrdim jos jednom gore napisano)
pozz


Upravo tako.To mi je jasno.Ali u ovom drugom primeru,sve dok ne pritisnem ctrl + z,mogu da unosim koliko god hocu znakova i u koliko god redova hocu.
U prvom primeru,cim pritisnem ENTER,on mi iskopira to sto sam uneo.Ono sto me interesuje je zasto mi ne dopusti (u 1. primeru) da unesem nekoliko redova,i potom po pritisku na ctrl + z,da mi sve sto sam uneo iskopira u izlaz.
znam da sam mozda malo naporan oko ovoga,ali stvarno me je zaintrigiralo,jednostavno je,ali ne radi ono sto ja ocekujem :).
[ toxi_programer @ 02.10.2006. 08:33 ] @
U V.S.6 i TurboC-u i prvi i drugi primer rade isto. S tim sto se U VS6 nista ne dogadja pritisno ti ctrl + z il ne pritisno. U turboC se "poštuje" ctrl + z ali sve jedno moras da pritisnes ENTER... Opet mi nisi rekao, koji kompajler koristis?
[ VukSta @ 02.10.2006. 18:48 ] @
da,kontam da moram da pritisnem enter posle ctrl + z,ako si na to mislio.ali meni ne rade isto i prvi i drugi primer.
kod oba primera se izvrsavanje programa zavrsava sa ctrl + z,i to je korektno.ali u drugom primerumi dozvoljava da string unesem nekoliko redova,i tek po pritisku na ctrl + z mi daje rezultat.
u prvom primeru,unesem jedan red,pritisnem enter,i on mi odmah to iskopira,ne mogu da unesem string u nekolko redova,pa da mi tek onda po pritisku na ctrl + z,on prikaze ceo ulaz iskopiran u izlaz.
to je ono sto me buni.zasto mi ne dozvoljava da kompletan unos obavim u nekoliko redova,pa da mi potom iskopira sve odjednom,kad mu dam znak za zavrsetak(odnosno ctrl +z),vec mi kopira red po red.
samo mi reci da li je logicka greska,ako jeste gde gresim,a ako je do kompajlera,onda ok.
mozda treba ovako da radi,al ne znam zasto.

koristim Codeblocks,kompajler je GNU GCC.
[ SuPeR_MaSteR @ 04.10.2006. 21:12 ] @
Mislim da je stvar u tome da ne mozes smestiti znak za novi red ('\n') u tip int i to je razlog sto ti ne dozvoljava unos u vise redova a onda ispis. Mozes to resiti uvodjenjem nizovne promenljive..
[ NrmMyth @ 05.10.2006. 17:57 ] @
Zasto ne mozes smjestiti '\n' u int??
[ SuPeR_MaSteR @ 06.10.2006. 00:01 ] @
ASCII kod tog znaka (10) se smesta u tip int. Ali ne moze se ispisati %d ili %f konverzijom sto je on u primeru koristio...
[ VukSta @ 15.10.2006. 14:34 ] @
ne nije problem u tome,ne vidim ni zasto bi bio.pokusao sam i da promenim kompajer,stvar se ne menja...
[ Dejan Lozanovic @ 29.10.2006. 19:12 ] @
Citat:
toxi_programer: @VukSta
- Ovo mi je zapalo za oko jer sam i ja kada sam ucio C naisao na isti problem, pitao sam i niko da da konkretan odgovor svi kao "zaobidji getchar()..." idr...
-No ako koristis getchar za uzimanje samo jednog znaka od korisnika( tesko da ces doci u pomenutu situaciju ali valja znati) posle poziva getchar() pozovi f-ju fflush( neki_tok ) gde je neki_tok npr stdin ili koji vec hoces da "ispraznis".


pa mislim da fflush nece pomoci jer getchar() "blokira" program dok ne dobije znak znaci fflush nece doci na red dok sam buffer ne bude flushovan. Jedino resenje za ove stvari je promeniti "disciplinu" samog terminala pod unix-olikim operativnim sistemima to se radi preko

Code:

#include <termios.h>
     int tcgetattr(int fd, struct termios *termios_p);


u termios_p treba ukljuciti ICANON, i tada je citanje/pisanje ide znak po znak.
[ toxi_programer @ 30.10.2006. 12:40 ] @
@Dejan Lozanovic
Stavio si recimo " a = getchar() " i ocekivao da korisnik otkuca 1 simbol a on je otkuco npr 2. Onda prvi znak ce biti dodeljen promenljivoj A i bice "izbrisan" iz bafera, a zatim ce bafer pokazivati na drugi znak koji je korisnik uneo pa ako opet budes koristio getchar() korisnik se nece pitati da unese znak jer bafer nije prazan. Ali ako pre drugog pozivanja uradis fflush() tog problema nece biti, zar ne?
[ Dejan Lozanovic @ 30.10.2006. 15:07 ] @
Pa opet kazem to sve zavisi od terminalske discipline, ako je "disciplina linijska" onda recimo ulaz i izlaz ce da izgledaju ovako
Code:

Dejan
Dejan


a ako je kakonicna onda to izgleda ovako

Code:

DDeejjaann



i ako je tvoj program potpuno isti, tj da rezimiram ti operativnom sistemu kazes da li ce i kako da baferise tvoj standardni ulaz.

[ Tiristor @ 30.10.2006. 20:33 ] @
Ja kada sam radio sa tim i kada mi je predstavljalo problem sam napravio funkciju, koja ucitava onoliko znakova koliko je potrebno, dalje ispistuje da li je sta uneseno i ako sta ima frti kroz jedan ciklus, kada vise nema i naidje da je korisnik uneo enter, onda ucitava enter i iskace iz petlje. To mi je omogucilo da mi cita sve znakove do novog reda i da mi ucita onoliko znakova koliko meni treba. ako treba 1 onda sam 1, a ostale ce samo kroz ciklus nalepiti na neku primenjivu promenjivu. Eto tako sam ja to sredio. Nekad mi je pravilo problem i to sto na primer treba da mi ucita jedan karakter, a za njim jos jedan i ako neko ukuca dva ili vise od jednom ono mi automatski prvi stavlja na prvu promenjivu, drugu na drugu i tako bi redom, dok ne dodeli sve sto je uneto sa tastature, tako da mi je ta funkcija i t resila. To je dobra stvar tih funkcija, jednom ih napravis i posle bas te briga, samo ih pozives. :)
Pozdrav