Ezzel mi a gond és hogyan lehetne a hibáit javítani?
Az egyik kérdésnél felmerült az alábbi - valami miatt sokat kritizált - kódrészlet:
std::ifstream ifs("test.txt");
ifs.open();
while(!ifs.eof()) {
// ...
}
Egyáltalán nem ismerem a C++ nyelvet (C#-pban és PHP-ban fejlesztek), de ezt a mintát kezdő programozóként én is nagyon sok helyen látom. Valaki felvilágosítana, hogy mi ezzel a gond?
Amik így első körben eszembe jutnak:
1) Nem vizsgáljuk meg, hogy sikerült-e a fájlt megnyitni.
2) Ha netán sikerült és a kód lefut, nem zárjuk le a megnyitott fájlt.
De mi van még?
Két dologba tudnék belekötni:
1. Hibakezelés teljes hiánya
2. Attól függően, hogy mi van a "// ..." helyén, talán soha nem kerülsz a fájl végére, és akkor végtelen ciklusban vagy.
Itt van egyébként szinte ugyanannak a de facto standard változata: [link]
1. Nem létezik olyan függvény hogy ifs.open();
Az open()-nek 2 paramétere van, ami közül a második default értékkel rendelkezik. Paraméterek nélkül le sem fordul.
2. Az ifstream konstruktora itt implicit meghívja a megfelelő paraméterezéssel az open függvényt, nem kell újra meghívni.
3. Az olvasás nem csak EOF miatt hiúsulhat meg. Olvasási hiba, logikai hiba, stb. Lehet hogy meg sem sikerül nyitni a fájlt. while(!ifs.eof()) helyett legyen while(ifs.good()) ami akkor igaz ha eof() fail() és bad() hamis.
4. Nincs lezárva a fájl.
1, 2: talált
3: "while(ifs.good())" még mindig rossz
4: a destructor lezárja
#4 Ami azt illeti senki sem szereti az okoskodó embereket akik tényekkel nem támasztják alá állításukat. Nem is lehet őket komolyan venni.
A good() egy teljesen elfogadott módszer (ezt #5 által linkelt oldalon is leírják többek között), a fájl lezárása pedig valóban nem történt meg így igaz az állítás. Ez egy kódrészlet amit nem tudjuk honnan vágtak ki és hogy használják fel. Lehet hogy valaki a beolvasás és feldolgozást követően ki akarja írni az eredményeket ugyan abba a fájlba és a destruktor még mindig nem hívódik meg, így teljesen elfogadott azt lezárni manuálisan ha már nem használjuk. A while előtt is meg szokás ejteni egy olvasást ilyen sorrendben:
//olvas
while {
//feldolgoz
//olvas
}
Így minden olvasás után, de feldolgozás előtt ellenőrizve lesz hogy helyes e a beolvasott adat. Opcionálisan lehet írni hibakezelést is.
Lehet hogy arra gondol hogy nem szokás a flageket ellenőrizni ha megteszi helyetted egy függvény? Pl.:
while(ifs>>be) vagy while(getline(ifs,be)) ? De ez nem teszi hibássá a flagek ellenőrzését, főleg hogy a példa általános módon erre hivatkozott és semmi sem utal a beolvasás és feldolgozás módjára.
"A good() egy teljesen elfogadott módszer, ezt #5 által linkelt oldalon is leírják többek között"
Így ne hivatkozz arra a kérdésre, ha nem olvastad el a válaszokat, vagy nem értetted meg.
Nem arról van szó, hogy jó vagy nem jó a good(). ITT a good() azért (szintén) nem jó, mert a beolvasás előtt csinálod.
#8
Látom azért van itt olyan is aki nem okoskodásnak tekinti, ha valamire azt mondják, hogy nem jó, hanem utána jár annak, hogy miért nem.
# többieknek
De itt egy konkrét példa a rossz megoldásra, a flagek olvasási kísérlet után állítódnak be, üres fájlnál is lefut az alábbi ciklus, és meghatározatlan értéke lesz az 'a' változónak.
while(!ifs.good())
{
int a;
ifs >> a;
// do something with variable a
}
Aki ilyen kódot ír annak adni kell egy tockost:
//olvas
while {
//feldolgoz
//olvas
}
Gondoltam a végére belinkelek egy tutorialt ( [link] ), de hát ott is rosszul van megírva, kommentek közt van egy javítás, de félig az is hibás.
@#8: "ITT a good() azért (szintén) nem jó, mert a beolvasás előtt csinálod."
#6-os írta hogy a good() elfogadott módszer a beolvasás tesztelésére, még példát is írt. Te meg visszaírod hogy a good azért nem jó mert beolvasás előtt csinálja? Olvasd már el a válaszát, nekem úgy tűnik TE nem értetted meg. "Minden olvasás UTÁN, de feldolgozás ELŐTT ellenőrizve lesz [...]"
@#9: A példád neked is azért hibás mert a kódod ilyen sorrendben kerül végrehajtásra:
ellenőriz
olvas
feldolgoz
E helyett:
olvas
ellenőriz
feldolgoz
Nem arról van szó itt hogy a good() hibás hanem arról hogy a példád abszolút hülyeség. Beolvasás után miért nem ellenőrzöd hogy sikerült e beolvasni? Wtf? Nem lenne ésszerű megnézni hogy elérted e a fájl végét? A tockosodat meg küld pl. a cppreference szerkesztőjének. Más sok mindent kikiáltottál hibásnak de azt még soha nem írtad le hogy szerinted mi az az általános megoldás ami mindenre működik és helyes? #6-tól láttunk ilyen megoldást. A helyett hogy másokat kritizálsz miért nem válaszolsz valami értelmeset?
Ez jobbnak tűnik?
while(1) {
//beolvas
if(!in.good()) break; //ellenőriz
//feldolgoz
}
Egyes függvények a beolvasást és az ellenőrzés részét összevonják egybe, mások nem.
A kérdező példájában egy szó sem volt a beolvasás és feldolgozás módjáról és helyéről, ezért nem értem miért feltételezd azt, hogy az rosszul lesz megoldva? Mindenki el tud rontani egy jó kódot hülyeséggel. Attól hogy rosszul használod a good() függvényt az még nem lesz rossz.
Kapcsolódó kérdések:
Minden jog fenntartva © 2024, www.gyakorikerdesek.hu
GYIK | Szabályzat | Jogi nyilatkozat | Adatvédelem | Cookie beállítások | WebMinute Kft. | Facebook | Kapcsolat: info(kukac)gyakorikerdesek.hu
Ha kifogással szeretne élni valamely tartalommal kapcsolatban, kérjük jelezze e-mailes elérhetőségünkön!