[so] Demo curs 2 inchidere stdin

Andra Danciu andradanciu1997 at gmail.com
Sun Mar 3 13:40:57 EET 2019


Buna, Darius,

Multumesc mult pentru explicatie!

Andra

În dum., 3 mar. 2019 la 13:25, Darius Mihai <dariusmihaim at gmail.com> a
scris:

> On Sun, Mar 3, 2019 at 1:19 PM Adrian Șendroiu via so
> <so at cursuri.cs.pub.ro> wrote:
> >
> > On Sun, 3 Mar 2019 at 13:05, Andra Danciu via so <so at cursuri.cs.pub.ro>
> 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
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://cursuri.cs.pub.ro/pipermail/so/attachments/20190303/cee7c837/attachment.html>


More information about the so mailing list