Problem med att återöppna ifstream

Här diskuteras programmering och utveckling
m!rage
Inlägg: 2550
Blev medlem: 28 apr 2009, 21:47
OS: Arch Linux
Ort: Lund

Problem med att återöppna ifstream

Inlägg 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?
Användarvisningsbild
mcNisse
Inlägg: 5211
Blev medlem: 06 feb 2007, 20:51
OS: Debian
Utgåva: Vet inte/ingen utgåva passar

Re: Problem med att återöppna ifstream

Inlägg 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...
m!rage
Inlägg: 2550
Blev medlem: 28 apr 2009, 21:47
OS: Arch Linux
Ort: Lund

Re: Problem med att återöppna ifstream

Inlägg 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.
m!rage
Inlägg: 2550
Blev medlem: 28 apr 2009, 21:47
OS: Arch Linux
Ort: Lund

Re: Problem med att återöppna ifstream

Inlägg 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...
Användarvisningsbild
Substrata
Inlägg: 71
Blev medlem: 13 apr 2010, 11:01
OS: Arch Linux
Utgåva: Vet inte/ingen utgåva passar

Re: Problem med att återöppna ifstream

Inlägg 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.
m!rage
Inlägg: 2550
Blev medlem: 28 apr 2009, 21:47
OS: Arch Linux
Ort: Lund

Re: Problem med att återöppna ifstream

Inlägg 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
Användarvisningsbild
Substrata
Inlägg: 71
Blev medlem: 13 apr 2010, 11:01
OS: Arch Linux
Utgåva: Vet inte/ingen utgåva passar

Re: Problem med att återöppna ifstream

Inlägg 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.
m!rage
Inlägg: 2550
Blev medlem: 28 apr 2009, 21:47
OS: Arch Linux
Ort: Lund

Re: Problem med att återöppna ifstream

Inlägg av m!rage »

Fattar inte riktigt... Kan du ge ett exempel?
Användarvisningsbild
Substrata
Inlägg: 71
Blev medlem: 13 apr 2010, 11:01
OS: Arch Linux
Utgåva: Vet inte/ingen utgåva passar

Re: Problem med att återöppna ifstream

Inlägg 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.
m!rage
Inlägg: 2550
Blev medlem: 28 apr 2009, 21:47
OS: Arch Linux
Ort: Lund

Re: Problem med att återöppna ifstream

Inlägg 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?
Användarvisningsbild
Substrata
Inlägg: 71
Blev medlem: 13 apr 2010, 11:01
OS: Arch Linux
Utgåva: Vet inte/ingen utgåva passar

Re: Problem med att återöppna ifstream

Inlägg 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...)
Skriv svar

Återgå till "Programmering och webbdesign"