Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien

[c++]iostream library, regels inlezen.

Pagina: 1
Acties:

  • RickN
  • Registratie: December 2001
  • Laatst online: 14-06 10:52
Ik zit voor de fun een paar programmeer opgaven te maken en daar moet je regelmatig input regel voor regel inlezen en die dan verwerken. Dus RickN typt:


C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream.h>

int main()
{
  char buffer[256];
  int resultaat;

  while (!cin.eof())
  {
    cin.getline(buffer,256);

    resultaat = verwerk(buffer);

    cout << resultaat << endl;
  };
}


Leek me redelijk basic. Nou zit ik te testen, met een file met 5 te verwerken regels, blijk ik 6 output regels te krijgen?! Als ik die file in een hexeditor open blijkt dat na de laatste regel die afgesloten wordt met een LF (werk onder linux) nog een null-byte te staan (al heb ik gemerkt dat dit niet altijd zo is). Nu vind cin.eof() dus dat we na de laatste regel nog niet aan het einde zijn en dat er nog één regel moet worden verwerkt. Dat vind ik dus vreemd, een null-byte is toch geen data meer? Ik heb het nu opgelost door er het volgende van te maken:

C++:
1
2
3
4
while (cin.getline(buffer,256))
{
  ....
}


Dat werkt, maar ik vind het zo raar dat ik een file doorloop zonder op eof() te testen. En waarom snap getline() wel dat een nullbyte geen data meer is en eof() niet? Is dit de bedoeling van istream klasse? Zo ja, waar is de eof() methode dan voor? Of moet ik gewoon wel op eof() testen en na elke getline() controleren of ik zinnige data heb gelezen?

Basically, wat is "best practice" bij het regel voor regel (maar eigenlijk in het algemeen) doorlopen van een file?

edit:
Misschien is het handig te vermelden dat ik de data vanuit een file naar m'n progje pipe, vandaar dat ik cin gebruik.

[ Voor 12% gewijzigd door RickN op 21-11-2002 19:41 ]

He who knows only his own side of the case knows little of that.


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03:19

.oisyn

Moderator Devschuur®

Demotivational Speaker

tja, een \0 byte in een text bestand zou in principe gewoon niet mogen. Het is trouwens beter om de lijnen in te lezen in een std::string, dan krijg je ook geen last van dat ie te weinig van een lange lijn inleest

C++:
1
2
3
4
5
6
#include <string>

using namespace std;

string str;
getline (cin, str);


je kunt nog wel evt kijken of de lengte van de laatste regel groter dan 0 is, zo ja, dan zit er dus nog een geldig character in

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • RickN
  • Registratie: December 2001
  • Laatst online: 14-06 10:52
.oisyn schreef op 21 November 2002 @ 19:39:
tja, een \0 byte in een text bestand zou in principe gewoon niet mogen. Het is trouwens beter om de lijnen in te lezen in een std::string, dan krijg je ook geen last van dat ie te weinig van een lange lijn inleest

C++:
1
2
3
4
5
6
#include <string>

using namespace std;

string str;
getline (cin, str);


je kunt nog wel evt kijken of de lengte van de laatste regel groter dan 0 is, zo ja, dan zit er dus nog een geldig character in
Ja, ik vond het ook al vaag, maar ik heb de file gewoon met touch aangemaakt en er daarna met echo en >> data aan geappend....

Btw, getline(cin,str) is dat hetzelfde als cin.getline(str)???

[ Voor 5% gewijzigd door RickN op 21-11-2002 20:12 ]

He who knows only his own side of the case knows little of that.


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03:19

.oisyn

Moderator Devschuur®

Demotivational Speaker

nee, die losse getline () is een aparte versie voor std::string, dan hoef je dus niet met character arrays te werken (en dan zit je dus ook niet aan een maximum buffergrootte)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • RickN
  • Registratie: December 2001
  • Laatst online: 14-06 10:52
.oisyn schreef op 21 November 2002 @ 19:45:
...... (en dan zit je dus ook niet aan een maximum buffergrootte)
dat is natuurlijk wel handig :9~

He who knows only his own side of the case knows little of that.


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 13-09 00:05
Om terug te komen op eof(), dat geeft alleen aan dat de laatste read-actie tegen een end-of-file aanliep, maar eof() is niet helderziende. Ook als je EOF nog niet gelezen hebt, kan je getline() falen. Maar jij gebruikt daarna toch het resultaat.

In een textfile tellen 0-bytes na de laatste \n overigens niet, IIRC - hoeveel regels lees je succesvol?

PS. gebruik <iostream> ipv <iostream.h>, dan heb je de std:: versies, in plaats van de 1997 versies van iostream.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


Verwijderd

RickN schreef op 21 november 2002 @ 19:24:
C++:
1
2
3
4
while (cin.getline(buffer,256))
{
  ....
}


Dat werkt, maar ik vind het zo raar dat ik een file doorloop zonder op eof() te testen. En waarom snap getline() wel dat een nullbyte geen data meer is en eof() niet? Is dit de bedoeling van istream klasse? Zo ja, waar is de eof() methode dan voor? Of moet ik gewoon wel op eof() testen en na elke getline() controleren of ik zinnige data heb gelezen?
basic_istream::getline return een basic_istream&, daarvan wordt vervolgens de ge-erfte basic_ios::operator void* member gebruikt die alleen een null pointer return-t als de failbit of badbit van de stream ge-set zijn, zodat while kan beslissen of er weer geloopt moet worden.

  • RickN
  • Registratie: December 2001
  • Laatst online: 14-06 10:52
MSalters schreef op 21 November 2002 @ 20:33:
Om terug te komen op eof(), dat geeft alleen aan dat de laatste read-actie tegen een end-of-file aanliep, maar eof() is niet helderziende. Ook als je EOF nog niet gelezen hebt, kan je getline() falen. Maar jij gebruikt daarna toch het resultaat.
Ik lees net ergens dat aangeraden wordt om de volgende constructie te gebruiken:

C++:
1
2
3
4
while(cin)
{
  cin.getline(buffer,256);
};


Dit omdat je dan niet in een oneindige loop terechtkomt als een errorvlag van je istream object gezet wordt waardoor het object niet meer beschikbaar is. Dit is natuurlijk vooral van belang wanneer je formatted input doet. Die zelfde referentie vertelde ook dat cin.fail() eigenlijk de enige zinnige status conditie is (.eof() b.v. niet omdat een fout in de input dan een oneindige loop zou veroorzaken) en dat testen op cin.fail() eigenlijk hetzelfde is als testen op cin.

Nu zag ik dat cin.getline() als returnvalue cin geeft, dus lijkt de methode die ik heb gebruikt om m'n file te doorlopen hetzelfde is als testen op cin, alleen dan compacter.
PS. gebruik <iostream> ipv <iostream.h>, dan heb je de std:: versies, in plaats van de 1997 versies van iostream.
Zit er nog enige logica achter wanneer je wel .h achter een header file zet en wanneer niet? Heeft dit iets te maken met het wel of niet hoeven toevoegen van namespace std? Of zijn dat die <cheader> includes waarbij dat niet meer hoeft?

* RickN is confused......

[ Voor 4% gewijzigd door RickN op 21-11-2002 21:01 ]

He who knows only his own side of the case knows little of that.


Verwijderd

RickN schreef op 21 November 2002 @ 21:00:
Zit er nog enige logica achter wanneer je wel .h achter een header file zet en wanneer niet? Heeft dit iets te maken met het wel of niet hoeven toevoegen van namespace std? Of zijn dat die <cheader> includes waarbij dat niet meer hoeft?
De logica is dat de C++ standard library headers geen .h gebruiken. Een leverancier kan er voor kiezen ook .h versies mee te leveren (met wat voor inhoud dan ook), maar het gebruik daarvan is uiteraard nonportable.

[ Voor 3% gewijzigd door Verwijderd op 21-11-2002 21:09 ]


  • RickN
  • Registratie: December 2001
  • Laatst online: 14-06 10:52
Verwijderd schreef op 21 November 2002 @ 21:09:
[...]

De logica is dat de C++ standard library headers geen .h gebruiken. Een leverancier kan er voor kiezen ook .h versies mee te leveren (met wat voor inhoud dan ook), maar het gebruik daarvan is uiteraard nonportable.
Aah, da's tenminste duidelijkheid...
En dingen als math.h, dat zijn C libraries en die gebruiken weer wel .h?

He who knows only his own side of the case knows little of that.


Verwijderd

RickN schreef op 21 November 2002 @ 21:10:
[...]

Aah, da's tenminste duidelijkheid...
En dingen als math.h, dat zijn C libraries en die gebruiken weer wel .h?
De C standard library gebruikt inderdaad .h extensies. Echter:
.oisyn schreef op 17 November 2002 @ 16:04:
in C++ zijn alle C-headers zonder .h en met c ervoor

dus:
#include <cstdio>
#include <cstdlib>
#include <cmath>
Verwijderd schreef op 17 november 2002 @ 16:53:
het verschil is dat de cname headers al hun prut in namespace std definieren/declareren.
Dit alles dus omdat C standard library stuff in de C headers niet netjes in een namespace staat.

[ Voor 35% gewijzigd door Verwijderd op 21-11-2002 21:19 ]

Pagina: 1