Buna, Darius, Multumesc mult pentru explicatie!
Andra În dum., 3 mar. 2019 la 13:25, Darius Mihai <[email protected]> a scris: > On Sun, Mar 3, 2019 at 1:19 PM Adrian Șendroiu via so > <[email protected]> wrote: > > > > On Sun, 3 Mar 2019 at 13:05, Andra Danciu via so <[email protected]> > wrote: > > > > > > Hello! > > > > > > La cursul 2, la unul dintre demo-uri, Razvan Deaconescu a dat close pe > stdin, a deschis un fisier si a citit un string cu scanf, presupunand ca > scanf-ul va citi din fisier. La curs acest demo nu a mers, nu imi explic de > ce. La mine a functionat. Am dat insa de un comportament ciudat. > > > > > > Acestui cod i-am dat ca argumente 3 fisiere random cu text in ele: > > > https://pastebin.com/xhy4gt6d > > > > > > La stdout se afiseaza primele 3 cuvinte din primul fisier, in loc sa > afiseze primul cuvant din fiecare fisier. Fisierele sunt, cumva, > serializate desi le inchid inainte sa citesc tot continutul (nu imi va citi > nimic din fisierul 2 pana nu ajunge la finalul primului fisier). Care e > explicatia? > > > > Salut, > > > > Explicația este că funcțiile din stdio fac buffering. Primul scanf > > citește cu read într-un buffer mai mare, iar următoarele vor întoarce > > date direct din buffer, fără să mai citească din fișier. scanf n-are > > de unde să știe că între timp ai închis și redeschis file descriptorul > > asociat lui stdin. > > Bună, Andra, > > Așa cum a spus și Adrian, problema este combinarea funcțiilor de > sistem (open) cu funcții de bibliotecă (scanf). Cu toate că > într-adevăr stdio folosește implicit file descriptor-ul 0 pentru a > citi, iar close + open îl vor suprascrie, primul scanf va umple > buffer-ul implicit al stdin cu date din primul fișier. Tu chiar dacă > faci close pe stdin, funcțiile open și close sunt transmise direct > sistemului de operare, iar funcțiile de bibliotecă nu vor goli > buffer-ul. > > Abordarea coretă este: > - folosești freopen pentru a redeschide stdin pentru a citi din alt > fișier > - folosești read pentru a citi datele din fișiere > > Dacă vrei să folosești neapărat close + open + scanf, trebuie să > declari buffer-ul stdin ca NULL folosind setbuf(stdin, NULL); > > Darius >
_______________________________________________ http://ocw.cs.pub.ro/courses/so/info/lista-discutii
