Sida 1 av 1
Problem med att återöppna ifstream
Postat: 17 mar 2010, 18:41
av m!rage
Har följande kod utklippt från ett större program:
Kod: Markera allt
#include <cstdlib>
#include <iostream>
#include <fstream>
using namespace std;
ifstream infil;
void skrivUt()
{
infil.open("kassabok.txt");
if (!infil) {
cout << "Kunde inte öppna fil att läsa från!";
cin.get();
exit(1);
}
string rad;
while(getline(infil, rad)) {
cout << rad << endl;
}
infil.close();
}
int main()
{
skrivUt();
skrivUt();
}
Kompilerar den med kommandot:
Kod: Markera allt
g++ -Wall -o skriva_ut_test.exe skriva_ut_test.cpp
Om jag kompilerar och kör programmet i Linux fungerar det som det ska, men i MinGW i Windows misslyckas det andra gången filen öppnas, jag får alltså utskriften "Kunde inte öppna fil att läsa från!" efter att innehållet skrivits ut en gång. Varför blir det så här? I Borlands C++-kompilator som finns i skolan fungerar det utan problem och även om jag bygger i Linux. Bugg i g++?
EDIT:
Kod: Markera allt
anton@saavedro:~$ g++ --version
g++ (Ubuntu 4.4.3-3ubuntu3) 4.4.3
...
Kod: Markera allt
D:\MinGW_5.1.4\bin>g++.exe --version
g++ (GCC) 3.4.5 (mingw-vista special r3)
...
Kan det vara så att 3.4.5 är för gammal helt enkelt?
Re: Problem med att återöppna ifstream
Postat: 17 mar 2010, 23:11
av mcNisse
m!rage skrev:Varför blir det så här? I Borlands C++-kompilator som finns i skolan fungerar det utan problem och även om jag bygger i Linux. Bugg i g++?
Det ser ut som du har rätt, bug i g++. Skulle tro att infil.close() misslyckas. Du kan ju testa att lägga in en enorm sleep mellan läsningarna och kolla om filen fortfarande är öppen.
Windows har problem med filhantering...
Re: Problem med att återöppna ifstream
Postat: 22 mar 2010, 09:16
av m!rage
Uppdaterade nyss MinGW till v 5.1.6 men det hjälpte inte, den använder fortfarande gcc 3.4. Kan man tvinga den att ladda ner och installera version 4 istället? Har provat att installera både Current och Candidate men det är ingen skillnad.
Re: Problem med att återöppna ifstream
Postat: 12 apr 2010, 08:24
av m!rage
Men vad fan är det frågan om? Nu har jag gcc version 4.40 i MinGW men det fungerar fortfarande inte
EDIT: den kompilerar inte med den nya, ska försöka fixa det...
Re: Problem med att återöppna ifstream
Postat: 13 apr 2010, 11:06
av Substrata
Noterar att du deklarerar variabeln utanför det scope det används i. Det betyder att objektet förmodligen behåller state mellan anropen, och kan vara anledningen till att det blir fel. Prova att deklarera inom funktionsblocket.
Re: Problem med att återöppna ifstream
Postat: 13 apr 2010, 19:35
av m!rage
Jaja det fungerade men det är ju fusk! Jag kanske behöver objektet i fler än en funktion!?

Men okej då, kan väl vänja mig vid att använda fstream's som engångs om jag måste. Fast det fungerar som sagt med både gcc4 och Borland att deklarera den globalt. Får väl bli så här eftersom jag inte lyckas fixa MinGW med gcc4
Re: Problem med att återöppna ifstream
Postat: 14 apr 2010, 00:10
av Substrata
Bind ifstream med ett objekt. Öppna filen i constructorn, stäng den i destructorn. När variabeln går ur scope så tas objektet bort. Nu garanterar kompilatorn att resursen stängs.
Re: Problem med att återöppna ifstream
Postat: 14 apr 2010, 14:59
av m!rage
Fattar inte riktigt... Kan du ge ett exempel?
Re: Problem med att återöppna ifstream
Postat: 20 apr 2010, 11:15
av Substrata
Glömde bort att komma tillbaka till tråden.
Kod: Markera allt
#include <iostream>
class Resource {
public:
Resource();
~Resource();
};
Resource::Resource()
{
std::cout << "Acquiring resouce..." << std::endl;
// open...
}
Resource::~Resource()
{
std::cout << "Releasing resource..." << std::endl;
// close...
}
int main(int argc, char **argv)
{
std::cout << "In main." << std::endl;
{
Resource r;
}
std::cout << "Exiting." << std::endl;
}
Kod: Markera allt
In main.
Acquiring resouce...
Releasing resource...
Exiting.
Kompilatorn garanterar att ~Resource körs när objeket går ur scope (alltså kodblocket det är definierat i), oavsett try/catch och sådant.
Re: Problem med att återöppna ifstream
Postat: 20 apr 2010, 17:29
av m!rage
Ok jag fattar ungefär. Så jag öppnar en ifstream i konstruktorn och gör allt jag ska göra med filen där, och stänger den sedan i destruktorn?
Re: Problem med att återöppna ifstream
Postat: 20 apr 2010, 17:47
av Substrata
Typ! Den här metoden används med fördel för att låsa semaforer runt kritiska sektioner i multitrådad kod. Om det förenklar just det här fallet låter jag vara osagt - det kan ju exempelvis bli problem att öppna filen - men metoden vill man känna till.
Edit: Gör inte _allt_ i constructorn. Lägg en ifstream &-getter i klassen och låt användaren av objektet använda den för att göra sitt. Constructorn och destructorn används här mest för att kompilatorn ska göra det som behövs före och efter du använder resursen (öppna, stänga, låsa, etc...)