JLI Spieleprogrammierung Foren-Übersicht JLI Spieleprogrammierung

 
 FAQFAQ   SuchenSuchen   MitgliederlisteMitgliederliste   BenutzergruppenBenutzergruppen 
 medals.php?sid=10c0d793ef041b073f7b6048b67dd3d4Medaillen   RegistrierenRegistrieren   ProfilProfil   Einloggen, um private Nachrichten zu lesenEinloggen, um private Nachrichten zu lesen   LoginLogin 

Echt mieses Problem mit Textdateien
Gehe zu Seite 1, 2, 3  Weiter
 
Neues Thema eröffnen   Neue Antwort erstellen    JLI Spieleprogrammierung Foren-Übersicht -> Fragen, Antworten und Kritik
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
Jonathan_Klein
Living Legend


Alter: 37
Anmeldedatum: 17.02.2003
Beiträge: 3433
Wohnort: Siegerland
Medaillen: Keine

BeitragVerfasst am: 09.03.2004, 15:18    Titel: Echt mieses Problem mit Textdateien Antworten mit Zitat

Ich habe vor einen Assistenten zu programmieren, der aus mehereen Teilen eine Webseite zusammenbastelt. Man schreibt also seine Texte und Inhalte einzeln, macht eine Navigationsleiste, und der Assistent erstellt daraus eine komplette Webseite.

Man erstellt eine Projektdatei, in der die einzennen Seiten die man haben will (Index, Links, Gästebuch...) aufgelistet sind.
Das Programm geht die Liste durch und setzt jeweils die Kopfzeile( mit der Navigation) und den Inhalt zu einer Datei zusammen.
Das soll der dann eigentlich mit jeder aufgelisteten Datei wiederholen.

Soweit die Theorie, hier der Quelltext:

int main()
{
char ProjektName[8];
char MainDatei[18], SeiteDatei[18], TitelDatei[18], NeueDatei[18], BottomDatei[18];
FILE * Datei=NULL, * DSeite, *DTitel, *DNeu, *DBottom;
char Puffer[255], Puffer2[255];
cout << "Meine Webseite V. 0.1\n";
cout << "Geben sie den Projektnamen ein: (max. 8 Buchstaben)\n";
cin >> ProjektName;
sprintf(MainDatei, "%s\\main.txt", ProjektName);
cout << "\nProjekt Main-Datei: " << MainDatei << "\n";


Datei=fopen(MainDatei, "r");
if(NULL==Datei)
{
cout << "\nDas Projekt existiert noch nicht!";
}
else //Wenn er die Projektdatei geladen hat
{
cout << "\nDas Projekt wurde geöffnet!\n";

while(!feof(Datei))
{

//Die nächste Datei aus der Projektdatei öffnen
fgets(Puffer, 255, Datei);
sprintf(SeiteDatei, "%s\\%s.txt", ProjektName, Puffer);
DSeite=fopen(SeiteDatei, "r");
if(NULL!=DSeite)
{
cout << SeiteDatei << " wurde geladen\n";
}

//Den Seitenkopf laden
sprintf(TitelDatei, "%s\\head.txt", ProjektName);
DTitel=fopen(TitelDatei, "r");
if(NULL==DTitel)
{
cout << "Fehler, " << TitelDatei << " konnte nicht geöffnet werden\n";
}

//Das Seitenende laden
sprintf(BottomDatei, "%s\\bottom.txt", ProjektName);
DBottom=fopen(BottomDatei, "r");
if(NULL==DBottom)
{
cout << "Fehler, " << BottomDatei << " konnte nich geöffnet werden\n";
}

//Die neue Datei erstellen
sprintf(NeueDatei, "%s\\%s.htm", ProjektName, Puffer);
DNeu=fopen(NeueDatei, "w");

while(!feof(DTitel))//Die Titeldatei in die NeueDatei schreiben
{
fgets(Puffer2, 255, DTitel);
fprintf(DNeu, Puffer2);
}
fclose(DTitel);

while(!feof(DSeite))//Die eigentliche Seite in die NeueDatei schreiben
{
fgets(Puffer2, 255, DSeite);
fprintf(DNeu, Puffer2);
}
fclose(DSeite);

while(!feof(DBottom))//Die Seitenendedatei hinzufügen
{
fgets(Puffer2, 255, DBottom);
fprintf(DNeu, Puffer2);
}
fclose(DBottom);


//und die neue Datei schließen
fclose(DNeu);

cout << "Datei erfolgreich hinzugefügt\n";
}


//ganz zum Schluss die Projektdatei schließen
fclose(Datei);

}

cout << "Ihr Projekt wurde erfolgreich abgeschlossen!\n";
cin >> ProjektName;
return 0;
}

Es gibt kine Compillingerrors, alles läuft wuunderbar, aber nur wenn in der "main.txt" bloß ein Eintrag ist (z. B. "index").
Sobald ich in die Datei

index
links

schreibe (also 2 Einträge) kommt folgende Fehlermeldung:

Debug Assertion Failed!
Programm f:\C++\Meine Webseite\Debug\Meine Webseite.exe
File: fprintf.c
Line: 56

Expression: str !=NULL

For information on how your programm can cause an assertion failure, see the VC++ dokumentation on asserts.


Keine Ahnung was das heißen soll.
Ich hab natürlich eine ganze Weile am Quelltext rumgebastelt.
Der Fehler kann ja eigentlich nur entstehen, wärend der den Eintrag in der main.txt ließt. Wenn in dieser nur 1 Eintrag (eine Reihe) steht, läuft es. Wenn man aber 2 Einträge macht, stürtzt er schon ab, BEVOR die erste Datei geschrieben ist. Aber zu diesem Zeitpunkt, kann es den Computer doch noch gar nicht ineteresieren, ob noch ein zweite Eintrag folgt oder nicht, er kann es eigenltich gar nicht wissen, weil er ja nicht nachschaut, aber es geht trotzdem nciht!

Aber da ein Computer ja angeblich logisch denkt, muss es ja eine Lösung geben!

Wäre echt cool, wenn mir jemadn helfen könnte.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
Jonathan_Klein
Living Legend


Alter: 37
Anmeldedatum: 17.02.2003
Beiträge: 3433
Wohnort: Siegerland
Medaillen: Keine

BeitragVerfasst am: 09.03.2004, 16:31    Titel: Antworten mit Zitat

Ich hab das gefühl, das es an dem Dateinamen liegt.

die funktion fgets sprintf und fopen scheinen nicht zusammen zu funktionieren.

fgets ließt nich nur bis zum Zeilenende, sondern schreibt das Zeilenende mit in den Puffer. Und dann kommt es zu Problemen, weil er den Dateinamen nicht finden kann. Das ist jedenfalls die einzigste erklärung, die ich finden kann.

Ich hab einfach mal die Schleife weggemacht, so dass sie nur einmal ausgeführt wird. Dabei kam folgendes heraus:
Wenn man nur eien Eintrag in der main.txt hat läuft alles gut.
Wenn man einen zweiten eintrag (in eine zweite reihe) macht, kommt die besagte Fehlermeldung.
Und wenn man hinter dem ersten Eintrag einen Zeilenumbruch macht, aber keinen 2 Eintrag schreibt, kommt der selbe Fehler. Daher vermute ich, das es nur an diesem Zeilenumbruchzeichen liegen kann.

aber wie ich das lösen kann weiß ich immer noch nicht.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
Nahar
Senior JLI'ler


Alter: 36
Anmeldedatum: 16.07.2003
Beiträge: 267

Medaillen: Keine

BeitragVerfasst am: 09.03.2004, 17:29    Titel: Antworten mit Zitat

Ja, natürlich. Du hast ein Umbrucjzeichen in der Datei, also steht da nicht Seite.htm sondern Seite.htm\n <- ungültiger Dateiname. Du musst das \n am Ende zuerst entfernen. Besonders dazu bitte ich dich endlich zu akzeptieren das die Sprache die du programmierst C++ ist, nciht C, und du also ruhig auch C++-Strings benutzen kannst Very Happy . Damit kannst du das Zeichen recht einfah entfernen.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Jonathan_Klein
Living Legend


Alter: 37
Anmeldedatum: 17.02.2003
Beiträge: 3433
Wohnort: Siegerland
Medaillen: Keine

BeitragVerfasst am: 10.03.2004, 12:56    Titel: Antworten mit Zitat

Danke, das hört sich so an als würde es funktionieren.
Nur steht im "Jetzt lerne ich DirectX 9 und Visual C++" nix über C++ Strings.

Ich wäre dir echt dankbar, wenn du ein Codebeispiel posten würdest, das die Umsetzung zeigt.

(Also im Prinzip dsa lesen des Dateinamens, löschen des \n und das anschließende Öffnen)
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
Hazel
JLI MVP
JLI MVP


Alter: 39
Anmeldedatum: 19.07.2002
Beiträge: 1761

Medaillen: Keine

BeitragVerfasst am: 10.03.2004, 13:06    Titel: Antworten mit Zitat

Code:

#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
#include<fstream>

using namespace std;

int main()
{
   string zeile;
   ifstream datei("test.txt");

   getline(datei, zeile);
   cout << zeile;

   datei.close();

   return 0;
}


Das \n wird nicht mit eingelesen... der Code sollte selbsterklärend sein. :)
_________________
*click* Dabuu!?
Twitter: http://twitter.com/Ollie_R
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Jonathan_Klein
Living Legend


Alter: 37
Anmeldedatum: 17.02.2003
Beiträge: 3433
Wohnort: Siegerland
Medaillen: Keine

BeitragVerfasst am: 10.03.2004, 13:28    Titel: Antworten mit Zitat

Ich habs leider noch nicht so ganz:

Also der Teil zum öffnen sah bisher so aus:

char MainDatei[18];
Datei=fopen(MainDatei, "r");
cout << "\nDas Projekt wurde geöffnet!\n";

while(!feof(Datei))
{
//Die nächste Datei aus der Projektdatei öffnen
fgets(Puffer, 255, Datei);
sprintf(SeiteDatei, "%s\\%s.txt", ProjektName, Puffer);
DSeite=fopen(SeiteDatei, "r");
//Jetz werden die Seiten z6usammenkopiert
}

Müsste ich den dann so abändern:?
strint Zeile ; entspricht char Puffer[255]
ifstream datei("test.txt"); entspricht Datei=fopen(MainDatei, "r")
getline(datei, zeile) entspricht fgets(Puffer, 255, Datei);

Dann hätte ich also quasi den korekten Dateinamen in der String-Variable "zeile"

dann müsste ich den kompletten Namen so machen.
sprintf(SeiteDatei, "%s\\%s.txt", ProjektName, zeile);

nimmt sprintf denn einen string statt char an?

wenn das so wie ich es dargestellt hab, funktioniert, müsste ich nur noch wissen, wie man mit getline(datei, zeile) rausfindet ob noch eine Zeile (Eintrag) vorhanden ist. Ist dann ja für ie Schleife wichtig.

Vielen dank schon mal im vorraus.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
Nahar
Senior JLI'ler


Alter: 36
Anmeldedatum: 16.07.2003
Beiträge: 267

Medaillen: Keine

BeitragVerfasst am: 10.03.2004, 13:32    Titel: Antworten mit Zitat

Gut, Hazel hat ja schon eine noch bessere Variante gepostet (Will auch mal, nicht immer nur Hazel Smile ) C++-Strings sehen so aus:
Code:

#include <iostream>
#include <string>

using namespace std;
 
int main(int argc, char* argv[]) // Ha, aber zumindest mit den richtigen Parametern, hat Hazel nicht *Komplex austob*
{
string str;
str="ich bin ein String Und zwar ein C++String";
cout << str;
str="Ich habe auch viele praktische Funktionen, z.B. kann man mich als CString umformatieren";
cout << str.c_str();
return 0;
}


Naja, etwas bescheiden das Beispiel, zugegeben, aber ich glaube das Prinzip lässt sich entnehmen.
Die diversen Funktionen kannst du ja der Kontexthilfe entnehmen

Halt, und noch was:
Nein, für %s solltest du glaub ich einen CString nehmen - string.c_str() liefert dir den.

Ob ein Eintrag vorhanden ist kannst du überprügfen indem du entweder überprüfst ob du am ende der Datei bsit, oder du testest einfach ob der String einen Wert hat. if(!string) = nicht am ende.

Ach ja, und ob du am Dateiende bist testest du mit if(!ifstream.eof()) ifstream ist dein Object von ifstream, Hazel nannte seins glaub Datei


Zuletzt bearbeitet von Nahar am 10.03.2004, 13:48, insgesamt 2-mal bearbeitet
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
The Lord of Programming
Living Legend


Alter: 37
Anmeldedatum: 14.03.2003
Beiträge: 3122

Medaillen: Keine

BeitragVerfasst am: 10.03.2004, 13:38    Titel: Antworten mit Zitat

Nahar hat Folgendes geschrieben:
Code:

string str;
str="ich bin ein String"+"Und zwar ein C++String";
cout << str;

Funzt nicht.
STL-Strings kann man nicht automatisch oder per typecaste konvertieren Wink
_________________
www.visualgamesentertainment.net
Current projects: RDTDC(1), JLI-Vor-Projekt, Tetris(-Tutorial), JLI-Format
(1) Realtime Developer Testing and Debugging Console


Anschlag, Anleitung zum Atombombenbau, Sprengkörper...
Hilf Schäuble! Damit er auch was findet...
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
Nahar
Senior JLI'ler


Alter: 36
Anmeldedatum: 16.07.2003
Beiträge: 267

Medaillen: Keine

BeitragVerfasst am: 10.03.2004, 13:47    Titel: Antworten mit Zitat

Hubs... hat niemand gesehen? Uffff.

Ähm *rotwerd* äh ja, gut. Öhm... *schwaffel* *schwaffel*
Stimmt, tut wirklich nicht.
Ist im Prinzip ja aber auch Schwachsinn, so wie ichs gerade gemacht hab. Kann man auch einfach zusammen schreiben. Und wenn der eine ein CString, der andere STL-String ist tuts.

War so frei und habs wegeditiert, sonst merkt sich ncoh jemand den Blödsinn. Wenn ich so einen Scheiss bau reicht das völlig aus.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Jonathan_Klein
Living Legend


Alter: 37
Anmeldedatum: 17.02.2003
Beiträge: 3433
Wohnort: Siegerland
Medaillen: Keine

BeitragVerfasst am: 10.03.2004, 13:50    Titel: Antworten mit Zitat

Achja, im Buch steht doch was über C++ Strings: S.244 (Kap 15 STL)

daraus hab ich jetzt folgendes gemacht

Ich hab den Code jetz soweit:


string Dateiname;

fgets(Puffer, 255, Datei);
Dateiname=Puffer;
Write("Dateiname=Puffer");
Dateiname.replace(Dateiname.find('\n'), 1, " ");
sprintf(SeiteDatei, "%s\\%s.txt", ProjektName, Dateiname.c_str());
Write("sprintf");
DSeite=fopen(SeiteDatei, "r");
Write("geöffner");
Nur das Dateiname.replace funktioniert noch nciht. Der soll ja eigentlich das \n Zeichen aus dem String löschen, damit fopnen keine Probleme mit dem Dateiname hat.

Ich bin dem Problem haarscharf auf den Fersen! Ich glaub es ist nur noch diese eine, winzige doofe Zeile Programmcode, die mich von meinem Glück trennt. Doch wie muss sie richtig heißen?
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
The Lord of Programming
Living Legend


Alter: 37
Anmeldedatum: 14.03.2003
Beiträge: 3122

Medaillen: Keine

BeitragVerfasst am: 10.03.2004, 14:00    Titel: Antworten mit Zitat

Ich nehm jett mal an, dass sich das '\n' Zeichen gan am Ende des Strings befindet. Dann kannst du doch einfach schreiben:
Code:
Dateiname[Dateiname.size()-1]=' ';

_________________
www.visualgamesentertainment.net
Current projects: RDTDC(1), JLI-Vor-Projekt, Tetris(-Tutorial), JLI-Format
(1) Realtime Developer Testing and Debugging Console


Anschlag, Anleitung zum Atombombenbau, Sprengkörper...
Hilf Schäuble! Damit er auch was findet...


Zuletzt bearbeitet von The Lord of Programming am 10.03.2004, 14:01, insgesamt einmal bearbeitet
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
Jonathan_Klein
Living Legend


Alter: 37
Anmeldedatum: 17.02.2003
Beiträge: 3433
Wohnort: Siegerland
Medaillen: Keine

BeitragVerfasst am: 10.03.2004, 14:01    Titel: Antworten mit Zitat

Für die die nicht wissen was das Write("dsga") bedetet.

Das ist eine meiner meinung nach ziemlich nützliche Funktion zum debuggenvon programmen:

#inlcude <stdio.h>
void Write(char Text[])
{
FILE *Datei;
Datei=fopen("Error.txt", "a");
fprintf(Datei, "%s\n", Text);
fclose(Datei);
}


Da sieht man halt genau, nach welcher Reihe der ASbgestürtzt ist, und kann sonst auch viele Variablen und sonstiges in die Datei schreiben.

Nix tolles, aber sehr nützlich um Fehler zu finden.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
Hazel
JLI MVP
JLI MVP


Alter: 39
Anmeldedatum: 19.07.2002
Beiträge: 1761

Medaillen: Keine

BeitragVerfasst am: 10.03.2004, 14:03    Titel: Antworten mit Zitat

Jonathan_Klein hat Folgendes geschrieben:
Achja, im Buch steht doch was über C++ Strings: S.244 (Kap 15 STL)

daraus hab ich jetzt folgendes gemacht

Ich hab den Code jetz soweit:


string Dateiname;

fgets(Puffer, 255, Datei);
Dateiname=Puffer;
Write("Dateiname=Puffer");
Dateiname.replace(Dateiname.find('\n'), 1, " ");
sprintf(SeiteDatei, "%s\\%s.txt", ProjektName, Dateiname.c_str());
Write("sprintf");
DSeite=fopen(SeiteDatei, "r");
Write("geöffner");
Nur das Dateiname.replace funktioniert noch nciht. Der soll ja eigentlich das \n Zeichen aus dem String löschen, damit fopnen keine Probleme mit dem Dateiname hat.

Ich bin dem Problem haarscharf auf den Fersen! Ich glaub es ist nur noch diese eine, winzige doofe Zeile Programmcode, die mich von meinem Glück trennt. Doch wie muss sie richtig heißen?


Kannst du mal bitte code-Tags benutzen. Das zu lesen ist Quälerei. ;)

1. fgets solltest du durch getline ersetzen. Wenn schon STL dann ganz, anders machst du dir nur unnötig Probleme und Qrbeit.

2. Du solltest File-Streams benutzen wie ich, weil sie STL kompatibel sind.
_________________
*click* Dabuu!?
Twitter: http://twitter.com/Ollie_R


Zuletzt bearbeitet von Hazel am 10.03.2004, 14:06, insgesamt einmal bearbeitet
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Hazel
JLI MVP
JLI MVP


Alter: 39
Anmeldedatum: 19.07.2002
Beiträge: 1761

Medaillen: Keine

BeitragVerfasst am: 10.03.2004, 14:05    Titel: Antworten mit Zitat

The Lord of Programming hat Folgendes geschrieben:
Ich nehm jett mal an, dass sich das '\n' Zeichen gan am Ende des Strings befindet. Dann kannst du doch einfach schreiben:
Code:
Dateiname[Dateiname.size()-1]=' ';


Dateiname.resize(Dateiname.size() - 1) ist besser, weil dabei die Länge des Strings korrekt bleibt. Vermeidet weitere "mysteriöse" Bugs.
_________________
*click* Dabuu!?
Twitter: http://twitter.com/Ollie_R
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Nahar
Senior JLI'ler


Alter: 36
Anmeldedatum: 16.07.2003
Beiträge: 267

Medaillen: Keine

BeitragVerfasst am: 10.03.2004, 14:06    Titel: Antworten mit Zitat

@ Lordof: Bin jetzt nach dem von vorher vorsichtig, aber löscht du mit deiner Variante nciht das \0 Zeichen statt dem \n?
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Beiträge der letzten Zeit anzeigen:   
Neues Thema eröffnen   Neue Antwort erstellen    JLI Spieleprogrammierung Foren-Übersicht -> Fragen, Antworten und Kritik Alle Zeiten sind GMT
Gehe zu Seite 1, 2, 3  Weiter
Seite 1 von 3

 
Gehe zu:  
Du kannst keine Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum nicht antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.


Powered by phpBB © 2001, 2005 phpBB Group
Deutsche Übersetzung von phpBB.de

Impressum