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
