problem mit fstream
-
Wie kann man prüfen ob eine Variable gesetzt ist?
Ich möchte nun prüfen ob dateiadresse bereits mit einer Adresse initialisiert wurde. Wenn nicht soll eine eingabeaufforderung kommen.
Geht das vielleicht mitif(!dateiadresse)
-
Ob eine Variable gesetzt ist kannst Du nicht herausfinden. Du kannst nur schauen ob ein bestimmter Wert enthalten ist (eine nicht-gesetzte, sprich uninitialisierte Variable enthält Müll, bzw. bei Objekten Defaults).
Du kannst aber überprüfen ob einer Variable vom Typ std::string eine Sequenz zugewiesen wurde:
if (!dateiadresse.empty())
-
Ok, hab es angewandt und mein Programm etwas erweitert. Nun sagt der Debugger allerdings:
jump to case label
und verweist auf die Zeile wo
case 2:steht. Mein Programm sieht so aus:
#include <iostream> #include <string> #include <fstream> using namespace std; //Die Noten-Klasse class noten { public: int deutsch; int englisch; int mathe; int technik; }; //Die Schüler-Klasse class schueler { public: string nachname; string vorname; string strasse; int plz; string ort; noten n; }; int main(void) { int option; cout << "##############################" << endl << "Bitte waehlen Sie eine Option:" << endl << endl << "(1) Datei auslesen" << endl << "(2) Datei schreiben" << endl << "##############################" << endl; cin >> option; switch(option) { case 1: schueler a; char neu; //Angabe des Dateipfads string dateiadresse; cout << "Bitte geben Sie die Adresse der Datei ein: "; cin >> dateiadresse; //Auslesen der Datei ifstream lesen; lesen.open(dateiadresse.c_str()); while (lesen) { lesen >> a.nachname >> a.vorname >> a.strasse >> a.plz >> a.ort >> a.n.deutsch >> a.n.englisch >> a.n.mathe >> a.n.technik; //Um die Schleife zu verlassen bevor nicht weiter gelesen werden kann, dient dazu die doppelte Ausgabe der letzten Zeile zu vermeiden if(!lesen) break; //Auslesen der Datei cout << "Nachname: " << a.nachname << endl << "Vorname: " << a.vorname << endl << "Strasse: " << a.strasse << endl << "Postleitzahl: " << a.plz << endl << "Ort: " << a.ort << endl << "Deutsch-Note: " << a.n.deutsch << endl << "Englisch-Note: " << a.n.englisch << endl << "Mathematik-Note: " << a.n.mathe << endl << "Technologie-Note: " << a.n.technik << endl; cout << endl; } lesen.close(); break; case 2: if(!dateiadresse.empty()) { //Angabe des Dateipfads string dateiadresse; cout << "Bitte geben Sie die Adresse der Datei ein: "; cin >> dateiadresse; } do { //Eingabe der Daten für die Schüler-Klasse cout << "Nachname: "; cin >> a.nachname; cout << "Vorname: "; cin >> a.vorname; cout << "Strasse: "; cin >> a.strasse; cout << "Postleitzahl: "; cin >> a.plz; cout << "Ort: "; cin >> a.ort; //Eingabe der Daten für die Noten-Klasse cout << "Deutsch-Note: "; cin >> a.n.deutsch; cout << "Englisch-Note: "; cin >> a.n.englisch; cout << "Mathematik-Note: "; cin >> a.n.mathe; cout << "Technologie-Note: "; cin >> a.n.technik; //Schreiben der Datei ofstream schreiben; schreiben.open(dateiadresse.c_str(), ios_base::app); schreiben << a.nachname << "\n" << a.vorname << "\n" << a.strasse << "\n" << a.plz << "\n" << a.ort << "\n" << a.n.deutsch << "\n" << a.n.englisch << "\n" << a.n.mathe << "\n" << a.n.technik << "\n"; schreiben.close(); //Wiederholung der Schleife falls erwünscht cout << "Moechten Sie einen weiteren Schueler hinzufuegen?" << endl << "Antworten Sie bitte mit j fuer ja oder n fuer nein: "; cin >> neu; break; }; }while(neu=='j'); return 0; }
-
Lies dir doch mal die vollständige Meldung durch - ich tippe auf "jump to case label bypasses variable initializing" (oder so). Du solltest die Variablen besser nicht im switch() definieren, sondern davor - andernfalls wird der Konstruktor-Aufruf übergangen, wenn du bei einer anderen case-Marke landest.
-
Komplett siehts so aus:
72 D:\Desktop-Save\c++\Aufträge + Übungen\302 Schuelerverwaltung2\schuelerverwaltung2.cpp jump to case label
Von welcher Variable redest du?
Die zu überprüfende wird doch vor switsch definiert.
-
Lies einfach in der nächsten Zeile weiter

Und das Problem dürfte die Variable "dateiadresse" sein - wenn option==2 ist, überspringst du die Initialisierung (und die Abfrage des Dateinamen)
-
a, neu, lesen und dateiadresse

-
Hmm.. entweder ich verstehe nicht genau was ihr meintet oder es klappt nicht:
#include <iostream> #include <string> #include <fstream> using namespace std; //Die Noten-Klasse class noten { public: int deutsch; int englisch; int mathe; int technik; }; //Die Schüler-Klasse class schueler { public: string nachname; string vorname; string strasse; int plz; string ort; noten n; }; int main(void) { schueler a; char neu; //Angabe des Dateipfads string dateiadresse; cout << "Bitte geben Sie die Adresse der Datei ein: "; cin >> dateiadresse; //Abfrage der gewünschten Option int option; cout << "##############################" << endl << "Bitte waehlen Sie eine Option:" << endl << endl << "(1) Datei auslesen" << endl << "(2) Datei schreiben" << endl << "##############################" << endl; cin >> option; switch(option) { case 1: //Auslesen der Datei ifstream lesen; lesen.open(dateiadresse.c_str()); while (lesen) { lesen >> a.nachname >> a.vorname >> a.strasse >> a.plz >> a.ort >> a.n.deutsch >> a.n.englisch >> a.n.mathe >> a.n.technik; //Um die Schleife zu verlassen bevor nicht weiter gelesen werden kann, dient dazu die doppelte Ausgabe der letzten Zeile zu vermeiden if(!lesen) break; //Auslesen der Datei cout << "Nachname: " << a.nachname << endl << "Vorname: " << a.vorname << endl << "Strasse: " << a.strasse << endl << "Postleitzahl: " << a.plz << endl << "Ort: " << a.ort << endl << "Deutsch-Note: " << a.n.deutsch << endl << "Englisch-Note: " << a.n.englisch << endl << "Mathematik-Note: " << a.n.mathe << endl << "Technologie-Note: " << a.n.technik << endl; cout << endl; } lesen.close(); break; case 2: do { //Eingabe der Daten für die Schüler-Klasse cout << "Nachname: "; cin >> a.nachname; cout << "Vorname: "; cin >> a.vorname; cout << "Strasse: "; cin >> a.strasse; cout << "Postleitzahl: "; cin >> a.plz; cout << "Ort: "; cin >> a.ort; //Eingabe der Daten für die Noten-Klasse cout << "Deutsch-Note: "; cin >> a.n.deutsch; cout << "Englisch-Note: "; cin >> a.n.englisch; cout << "Mathematik-Note: "; cin >> a.n.mathe; cout << "Technologie-Note: "; cin >> a.n.technik; //Schreiben der Datei ofstream schreiben; schreiben.open(dateiadresse.c_str(), ios_base::app); schreiben << a.nachname << "\n" << a.vorname << "\n" << a.strasse << "\n" << a.plz << "\n" << a.ort << "\n" << a.n.deutsch << "\n" << a.n.englisch << "\n" << a.n.mathe << "\n" << a.n.technik << "\n"; schreiben.close(); //Wiederholung der Schleife falls erwünscht cout << "Moechten Sie einen weiteren Schueler hinzufuegen?" << endl << "Antworten Sie bitte mit j fuer ja oder n fuer nein: "; cin >> neu; break; }; }while(neu=='j'); return 0; }
-
Du darfst innerhalb eines Blocks ( "{ ... }" ) keine Variablen nach einem Label (hier: case-Marke) definieren.
switch(option) { // Block case 1: // Case-Marke //Auslesen der Datei ifstream lesen; // Definition (huch)
-
Wie wärs wenn man den ganzen case-Zweig einfach ordentlich klammert
switch(...) { case 1: { // irgendwas break; } case 2: { // irgendwas break; } }Dann klappt das auch mit den Variablen.
-
Wie ist das eigentlich mit den Schreibrechten? Kann man beliebig solche Dateien anlegen? Ich meine mittels einer Endlosschleife lässt sich ja eine "fieße" Datei schreiben. Kann man sich vor sowas nicht schützen? Wie siehts unter Linux eigentlich aus?
-
t1m0n schrieb:
Wie ist das eigentlich mit den Schreibrechten? Kann man beliebig solche Dateien anlegen? Ich meine mittels einer Endlosschleife lässt sich ja eine "fieße" Datei schreiben. Kann man sich vor sowas nicht schützen? Wie siehts unter Linux eigentlich aus?
man kann aber auch einen neuen thread eröffnen

-
wie kann das programm denn wissen wie es die strings in die variablen verteilt?
Abschnitt:
case 1: //Auslesen der Datei ifstream lesen; lesen.open(dateiadresse.c_str()); while (lesen) { lesen >> a.nachname >> a.vorname >> a.strasse >> a.plz >> a.ort >> a.n.deutsch >> a.n.englisch >> a.n.mathe >> a.n.technik; //Um die Schleife zu verlassen bevor nicht weiter gelesen werden kann, dient dazu die doppelte Ausgabe der letzten Zeile zu vermeiden if(!lesen) break; //Auslesen der Datei cout << "Nachname: " << a.nachname << endl << "Vorname: " << a.vorname << endl << "Strasse: " << a.strasse << endl << "Postleitzahl: " << a.plz << endl << "Ort: " << a.ort << endl << "Deutsch-Note: " << a.n.deutsch << endl << "Englisch-Note: " << a.n.englisch << endl << "Mathematik-Note: " << a.n.mathe << endl << "Technologie-Note: " << a.n.technik << endl; cout << endl; }
-
dieterneuermann schrieb:
wie kann das programm denn wissen wie es die strings in die variablen verteilt?
Abschnitt:
case 1: //Auslesen der Datei ifstream lesen; lesen.open(dateiadresse.c_str()); while (lesen) { lesen >> a.nachname >> a.vorname >> a.strasse >> a.plz >> a.ort >> a.n.deutsch >> a.n.englisch >> a.n.mathe >> a.n.technik; //Um die Schleife zu verlassen bevor nicht weiter gelesen werden kann, dient dazu die doppelte Ausgabe der letzten Zeile zu vermeiden if(!lesen) break; //Auslesen der Datei cout << "Nachname: " << a.nachname << endl << "Vorname: " << a.vorname << endl << "Strasse: " << a.strasse << endl << "Postleitzahl: " << a.plz << endl << "Ort: " << a.ort << endl << "Deutsch-Note: " << a.n.deutsch << endl << "Englisch-Note: " << a.n.englisch << endl << "Mathematik-Note: " << a.n.mathe << endl << "Technologie-Note: " << a.n.technik << endl; cout << endl; }Ähm.. ja, meine Worte...
-
dieterneuermann schrieb:
wie kann das programm denn wissen wie es die strings in die variablen verteilt?
Kurz: jedes Whitespace in der Eingabe (Leerzeichen, Tab, Newline) wird als Endemarke interpretiert. (bei Zahlenwerten beendet übrigens alles, was nicht als Zahl erkennbar ist, die Eingabeoperation)
-
heißt das die textdatei müsse so in etwa aussehen:
AnDerEckeWohn
Klaus
Brücke17
56187
Hamburg
6
5
4
3? wenn ja dann hab ich was gelernt
noch was:
a.n.englisch
was bedeutet da das n?
-
n ist ein Member der Klasse "schueler" in Timon's Klassenstruktur (das ist selber auch wieder ein struct, so daß du die Member-Aufrufe verketten kannst: a.n.englisch greift auf das Element "englisch" im inneren von a.n zu).
-
ach jetzt habe ich es entdeckt.
noten n war es.ich habe es beim ersten mal übersehen deswegen die frage?
die textdatei würde ihre arbeit in diesem sinne machen?
-
Ja, würde sie - wobei es reicht, alles auf eine Zeile zuschreiben und je ein Leerzeichen dazwischen zu setzen.
-
Ja, das Programm klappt einwandfrei.Bis auf Weiteres ist das die fertiggestellte Version:
#include <iostream> #include <conio.h> #include <string> #include <fstream> using namespace std; //Die Noten-Klasse class noten { public: int deutsch; int englisch; int mathe; int technik; }; //Die Schüler-Klasse class schueler { public: string nachname; string vorname; string strasse; int plz; string ort; noten n; }; int main(void) { schueler a; char neu; //Angabe des Dateipfads string dateiadresse; cout << "Bitte geben Sie die Adresse der Datei ein: "; cin >> dateiadresse; //Abfrage der gewünschten Option int option; cout << "##############################" << endl << "Bitte waehlen Sie eine Option:" << endl << endl << "(1) Datei auslesen" << endl << "(2) Datei schreiben" << endl << "##############################" << endl; cin >> option; switch(option) { case 1: { //Auslesen der Datei ifstream lesen; lesen.open(dateiadresse.c_str()); while (lesen) { lesen >> a.nachname >> a.vorname >> a.strasse >> a.plz >> a.ort >> a.n.deutsch >> a.n.englisch >> a.n.mathe >> a.n.technik; //Um die Schleife zu verlassen bevor nicht weiter gelesen werden kann, dient dazu die doppelte Ausgabe der letzten Zeile zu vermeiden if(!lesen) break; //Auslesen der Datei cout << "##############################" << endl << "Nachname: " << a.nachname << endl << "Vorname: " << a.vorname << endl << "Strasse: " << a.strasse << endl << "Postleitzahl: " << a.plz << endl << "Ort: " << a.ort << endl << "Deutsch-Note: " << a.n.deutsch << endl << "Englisch-Note: " << a.n.englisch << endl << "Mathematik-Note: " << a.n.mathe << endl << "Technologie-Note: " << a.n.technik << endl; cout << endl; } lesen.close(); getch(); break; } case 2: { do { //Eingabe der Daten für die Schüler-Klasse cout << "Nachname: "; cin >> a.nachname; cout << "Vorname: "; cin >> a.vorname; cout << "Strasse: "; cin >> a.strasse; cout << "Postleitzahl: "; cin >> a.plz; cout << "Ort: "; cin >> a.ort; //Eingabe der Daten für die Noten-Klasse cout << "Deutsch-Note: "; cin >> a.n.deutsch; cout << "Englisch-Note: "; cin >> a.n.englisch; cout << "Mathematik-Note: "; cin >> a.n.mathe; cout << "Technologie-Note: "; cin >> a.n.technik; //Schreiben der Datei ofstream schreiben; schreiben.open(dateiadresse.c_str(), ios_base::app); schreiben << a.nachname << "\n" << a.vorname << "\n" << a.strasse << "\n" << a.plz << "\n" << a.ort << "\n" << a.n.deutsch << "\n" << a.n.englisch << "\n" << a.n.mathe << "\n" << a.n.technik << "\n"; schreiben.close(); //Wiederholung der Schleife falls erwünscht cout << "Moechten Sie einen weiteren Schueler hinzufuegen?" << endl << "Antworten Sie bitte mit j fuer ja oder n fuer nein: "; cin >> neu; }while(neu=='j'); break; } }; return 0; }Da ihr mir aber was zum Thema Vektoren erzählt habt und mein Buch in dem übernächsten Kapitel damit anfängt werde ich ggf. noch eine neue Version hinterfragen müssen :p