c++ arbeiten mit dateien

namuen

Grünschnabel
Hi,
ich bin Neueinsteiger mit c++ und habe jetzt ein Problem mit einer Übungsaufgabe in meinem c++-Buch.
Aufgabe:
Schreiben Sie ein Programm stat.cpp, das eine Statistik für eine Textdatei ausgibt, deren Name eingegeben werden soll. Das Ergebnis soll eine Ausgabe folgender Art hervorbringen:

Anzahl der Zeichen = ...
Anzahl der Worte = ...
Anzhal der Zeilen = ...


Code:
#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>       //für exit()
#include <stdlib.h>
using namespace std;

int main(){
	ifstream quelle;
	cout << "Dateiname : ";
	string dateiname;
	cin >> dateiname;
	quelle.open(dateiname.c_str());
	if(!quelle){
		cerr << dateiname
		       << "kann nicht geöffnet werden";
		exit(-1);
	}
	char c;
	long zeichen = 0;
	long worte = 0;
	long zeilen = 0;
	bool wort = false;
	while(quelle.get(c)){
		if(c == '\n')	zeilen++;
		else			zeichen++;
		if(c >= 'A' && c<= 'Z' || c>='a' && c<='z')
			wort = true;                 //Wortanfang oder c ist in einem Wort
		else{                                   //Wenn c Leerzeichen ist
			if(wort)
				worte++;
			wort = false;
		}
		
	}
	quelle.close();     
	quelle.clear();
	cout << "Anzahl der Zeichen = " << zeichen << endl;
	cout << "Anzahl det Worte = "   << worte << endl;
	cout << "Anzahl der Zeilen = "  << zeilen << endl;
	system("PAUSE");
	return 0;

}

Wenn ich nun das Programm laufen lasse wird immer die Fehlermeldung das die Datei nicht geöffnet werden kann und der Dateiname wird auch nicht angezeigt.

1) Muss ich selber eine Textdatei erstellen und dann bei quelle.open den Dateinamen angeben?
2) Was genau macht dateiname.c_str()?
3) Ist in diesem Fall close() und clear() notwendig?

Schon mal vielen Dank für eure Hilfe.
 
Hi

1: Ja, wenn du keine Beispieldatei vorgegene bekommen hast musst du selbst eine erstellen.
Und den Dateiname solltest du ins laufende Programm eingeben, er wird bei cin ja abgefragt.

2: Es gibt verschiedene Arten, Strings zu speichern.
Eine wäre ein Array aus char (Einzelbuchstaben).
Der Umgang (Sachen drin suchen etc. etc.) mit dieser Art ist aber etwas umständlich.
Die von dir verwendete Stringklasse hat in sich drin zwar auch so ein char-Array,
zusätzlich aber noch häufig benötigte Funktionen.
Mit c_str bekommst du das pure char-Array wieder raus.
Das quelle.open braucht nämlich eins, kann mit der Stringklasse nicht umgehen.

3: Ja. Offene Dateien immer schließen.
 
Über Punkt 3 kann man diskutieren. Die heutigen Betriebssysteme schließen Dateien automatisch beim Beenden des Programms.
 
1: Das ist so minimal, dass das heute keinen mehr juckt.
2: Hmm.
3: Werden die heutigen System so schlau sein, die Zugriffe auf die Datei zu minimalisieren und am Ende zu schließen.
Nicht immer funktioniert die Automatik... Und trotzdem wenn man es vergisst geht nicht die Welt unter, da das System es/sie (meistens) selbst schließt.
 
Beim Punkt 3 meinte ich nicht Leistung etc.,
sondern Sachen wie Zugriffssperren für andere Programme.
So schlau, um die Absicht des Programmiers zu erkennen (die Datei nicht mehr zu verwenden)
werden die Systeme in absehbarer Zeit nicht werden.

Und zum 1:
Über diesen Punkt könnte man so schön lang diskutieren :)
Die Geräte werde immer besser, mehr Geschwindigkeit, mehr Speicher...
und die Programme "wachsen" mit.
Grafik. Grafik, Grafik, Video, Aero...
Was man dann letztendlich mit neuer Hardware und neuer Software machen kann,
ist ziemlich das selbe wie mit alter HW/SW.
Was könnte man dann alles mit neuer HW und alter (resourcenschonender) SW rausholen?
...
Vergleich Minimal-RAM XP/7: 64MB/1GB

Sag ja nicht, dass man jedem Bit hinterherrennen muss.
Und etwas Vergessen kann auch jeder.
Aber es ist doch wirklich nicht viel Aufwand, ein fclose hinzuschreiben...
unter Anderem solche "Faulheit" hat zu dem enormen Bedarfsanstieg geführt.
(Und der Drang, alles immer bunter und animierter zu machen.)
 
3: Werden die heutigen System so schlau sein, die Zugriffe auf die Datei zu minimalisieren und am Ende zu schließen.
Nicht immer funktioniert die Automatik... Und trotzdem wenn man es vergisst geht nicht die Welt unter, da das System es/sie (meistens) selbst schließt.
Nein, so "schlau" sind die Systeme nicht, können sie ohne hellseherische Fähigkeiten auch überhaupt nicht sein. Eine derartige Automatik seitens des Betriebssystems gibt es nicht. Dateideskriptoren sind eine in ihrer Anzahl beschränkte Systemressource. Schließt man sie nach Gebrauch nicht, wird irgendwann die maximale Anzahl offener Deskriptoren erreicht und der Prozess kann plötzlich keine Datei mehr lesen. Im schlimmsten Fall stürzt sogar das ganze System ab, weil auch andere Prozesse keine Dateien mehr öffnen können. Ein Deskriptorenleck ist somit ein klarer Programmierfehler. Das Argument „die Welt geht nicht unter“ zieht da nicht, das könnte man genauso bei Speicherlecks, Pufferüberläufen etc. bringen.

Abgesehen davon hat diese Diskussion mit der eigentlichen Frage 3) von namuen wenig zu tun. Ein .close() ist hier nicht unbedingt nötig, da der Dateideskriptor automatisch im Destruktor von ifstream sauber geschlossen wird. Wohlgemerkt vom Programm, nicht vom Betriebssystem beim Abräumen des Prozesses.

Grüße,
Matthias
 
Zurück