Wie schreibt der Compiler in eine Text-Datei ?



  • Hallo,

    ich möchte in eine Textdatei schreiben und das klappt auch soweit.
    Ich gebe mal ein Beispiel:
    Ich habe in der Textdatei in der ersten Zeile eine Zahl stehen z.B. 100.
    Ich kann diese Zahl auslesen und addieren und subtrahieren etc.

    Nun das Problem:
    Wenn ich von diesen 100, 200 abziehe, dann sind es ja -100. In der Textdatei stehen dann auch -100 allerdings mit einem Sonderzeichen dahinter und die nächste Zeile (in diesem Fall sollte dort eine Leerzeile sein) wird einfach entfernt. Das SOnderzeichen ist ein kleines Quadrat. Ich gehe davon aus, dass das ein "endl" ist. Aber warum steht es als Sonderzeichen dahinter ??
    Das Problem ergibt sich, sobald der Sprung über oder unter 0 gamacht wird. Also wenn ich von Hand -100 in die Datei eingebe, dann kann ich subtrahieren und addieren etc. solange ich im negativen Bereich bleibe. Gehe ich in den positiven Bereich, passiert das Gleiche wie vom Positiven in den Negativen.

    Weiß jemand woran das liegen könnte ??



  • Compiler, Betriebssystem, Editor, Code?



  • Schreibst du ganz zufällig binär in die Textdatei?

    C++ lernen und professionell anwenden schrieb:

    Standardmäßog wird eine Datei als Textdatei im sog. Textmodus geöffnet. Beim Lesen bzw. Schreiben einer Textdatei werden Steuerzeichen zum Kennzeichnen eines Zeilenwechsels oder des Dateiendes gesondert interpretiert und an das jeweilige Betriebssystem angepaßt. (sog. "Cooked Modus"). Bei einer im Binärmodus geöffneten Datei werden alle Bytes ohne jede Veränderung übertragen (sog. "RawModus").

    Caipi



  • Also mein Betriebssystem ist Windows XP und ich arbeite mit Microsoft Visual Studio 6.0.
    Die Eingabe in die Textdatei erfolgt über die Kommandozeile.....hier die Funktion:

    void Konto::auszahlen() {
    
    	string kntnr, pfad;
    	float auszahl;
    	float betrag;
    	char merk[10];
    	char tToday[20];
    	char dToday[20];
    
    	cout << "Bitte geben Sie ihre Kontonummer ein: " << endl;
    	cin >> kntnr;
    
    	pfad = "C:/Konto/Dateien/konten/" + kntnr + ".txt";
    
    	fstream pruefung(pfad.c_str());
    
    	if(!pruefung) {
    		cout << "Diese Konto existiert nicht!" << endl;
    		exit (-1);
    	}	else {
    			cout << "Wieviel moechten Sie sich auszahlen lassen ?" << endl;
    			cin >> auszahl;
    			if(auszahl < 0) {
    				cout << "Keine negativen Betraege eingeben!!" << endl;
    				exit (-1);
    			}
    
    			_strtime(tToday); //gibt die aktuelle Systemzeit an und schreibt es in tToday
    			_strdate(dToday); //gibt das aktuelle Systemdatum an und schreibt es in dToday
    
    			fstream file;
    			file.open(pfad.c_str(), ios::out | ios::app);
    			file << "Bar";
    			file << ";";
    			file << auszahl;
    			file << ";";
    			file << "-";
    			file << ";";
    			file << dToday;
    			file << ";";
    			file << tToday;
    			file << ";";
    			file << "Auszahlung";
    			file << ";";
    			file << endl;
    			file.close();
    
    			file.open(pfad.c_str(), ios::out | ios::in);
    			file.seekg(0);
    			file.getline(merk, 10);
    			cout << merk << endl;
    			betrag = atof(merk);
    		//	cout << "Vorher: " << betrag << endl;
    			betrag = betrag - auszahl;
    		//	cout << "Nachher: " << betrag << endl;
    			file.seekg(0);
    			file << betrag;
    			file << endl;
    			file.close();
    
    		}
    
    }
    


  • Normalerweise erzeugt man eine Datei neu, wenn man eine Ausgabe reinschreibt und vernudelt sie nicht irgendwie.



  • Dieser Kommentar hilft mir echt ungemein weiter.
    In der Datei stehen alle Buchungen und der aktuelle Kontostand, von daher kann sie nicht neu erzeugt werden.



  • Natürlich kann man, man muss sie nur vorher einlesen. Der Kommentator hat das Problem aber gut erkannt. Du überschreibst den Anfang der Datei mit dem neuen Wert... das geht natürlich nur so lange gut, wie der alte und der neue Wert die gleiche Anzahl an Stellen haben. Das komische Zeichen dahinter war dann wohl die Hälfte eines Zeilenumbruchs, die du nicht überschrieben hast.



  • Watercloud: Ich glaube ich weiss, was Du machen willst. Was Du brauchst ist eine feste Datensatzgroesse. Leider bin ich mit der C++-Standard-Stream-Library nicht allzu bewandert, also zeige ich Dir, wie man das mit der alten C-Library machen kann (in diesem Fall sogar mit variabler Datensatzgroesse):

    #include <stdlib.h>  // oder cstdlib
    #include <stdio.h>   // oder cstdio
    #include <time.h>    // oder ctime
    #include <string>
    
    typedef std::string String;
    
    const String dateiname( "buchungen.txt" );
    
    enum Auszahlungsmodus { BAR };
    enum Buchungstyp { AUSZAHLUNG };
    
    class Datensatz {
       public:
       String            Zeile;         // enthaelt den Datesatz als Zeile
       Auszahlungsmodus  Auszahlmodus;  // Bar, etc.
       double            Betrag;    
       long int          Datum;         // JJJJMMTT
       long int          Uhrzeit;       // HHMMSS
       Buchungstyp       Typ;           // Auszahlung, etc.
       Datensatz( void );
       ~Datensatz( void );
       bool laden( FILE* fp );
       void speichern( FILE* fp );
    };
    
    Datensatz::Datensatz( void ) : Auszahlmodus(BAR), Betrag(0.0), Datum(0L),
       Uhrzeit(0L), Typ(AUSZAHLUNG) { }
    Datensatz::~Datensatz( void ) { }
    
    bool Datensatz::laden( FILE* fp ) {
       char Zeilenpuffer[1024];
       if ( fgets( Zeilenpuffer, sizeof(Zeilenpuffer), fp ) == 0 ) {
          fprintf( stderr, "Dateiende erreicht!\n" );
          return false;
       }
       Zeile = Zeilenpuffer;
       size_t len = Zeile.size();
       if ( len > 0U && Zeile[len-1] == '\n' ) --len; // LF am Ende abschneiden
       if ( len > 0U && Zeile[len-1] == '\r' ) --len; // CR am Ende abschneiden
       Zeile.resize(len);
       char AuszModus[100];
       char BuchTyp[100];
       if ( sscanf( Zeile.c_str(), "%99s %lf %ld %ld %99s", AuszModus, &Betrag,
          &Datum, &Uhrzeit, BuchTyp ) != 5 ) {
          fprintf( stderr, "Fehlerhafter Datensatz: \"%s\"\n", Zeile.c_str() );
          return false;
       }
       String ausz_mod( AuszModus );
       String buch_typ( BuchTyp );
       if ( ausz_mod != "BAR" ) {
          fprintf( stderr, "Ungueltiges Feld \"Auszahlungsmodus\" in Datensatz"
             " \"%s\": \"%s\"", Zeile.c_str(), ausz_mod.c_str() );
          return false;
       }
       if ( buch_typ != "AUSZAHLUNG" ) {
          fprintf( stderr, "Ungueltiges Feld \"Buchungstyp\" in Datensatz"
             " \"%s\": \"%s\"", Zeile.c_str(), buch_typ.c_str() );
          return false;
       }
       // normalerweise muesste man evtl. weitere Pruefungen vornehmen,
       // und dann die Felder Auszahlmodus und Typ entsprechend setzen.
       Auszahlmodus = BAR;
       Typ = AUSZAHLUNG;
       return true;    
    }
    
    void Datensatz::speichern( FILE* fp ) {
       char Zeilenpuffer[1024];
       sprintf( Zeilenpuffer, "%s %f %ld %ld %s\n",
          ( Auszahlmodus == BAR ? "BAR" : "???" ), Betrag, Datum, Uhrzeit,
          ( Typ == AUSZAHLUNG ? "AUSZAHLUNG" : "???" ) );
       Zeile = Zeilenpuffer;
       fputs( Zeile.c_str(), fp );
    }
    
    void buchungen_anzeigen( void ) {
       FILE* fp = fopen( dateiname.c_str(), "r" );
       if ( fp == 0 ) { 
          printf( "Keine Buchungsdatei vorhanden -- wird erstellt.\n" );
          fp = fopen( dateiname.c_str(), "w" );
          if ( fp ) fclose( fp ); else { fprintf( stderr, "nicht erstellbar??\n" ); return; }
          fp = fopen( dateiname.c_str(), "r" );
          if ( fp == 0 ) { fprintf( stderr, "Haeh?? Datei nicht gefunden\n" ); return; }
       }
       Datensatz satz;
       for (;;) {
          if ( !satz.laden( fp ) ) break;
          printf( "%-20.20s %10.2f %02d.%02d.%04d %02d.%02d Uhr %-20.20s\n",
             ( satz.Auszahlmodus == BAR ? "BAR" : "???" ), satz.Betrag,
             satz.Datum % 100L, ( satz.Datum / 100L ) % 100L, ( satz.Datum / 10000L ) % 10000L,
             ( satz.Uhrzeit / 10000L ) % 100L, ( satz.Uhrzeit / 100L ) % 100L,
             ( satz.Typ == AUSZAHLUNG ? "AUSZAHLUNG" : "???" ) );
       }
       fclose( fp );
    }
    
    String eingabe_lesen( void ) {
       char buf[1024];
       buf[0] = '\0';
       fgets( buf, sizeof(buf), stdin );
       String tmp( buf );
       size_t len = tmp.size();
       if ( len > 0U && tmp[len-1U] == '\n' ) --len;
       if ( len > 0U && tmp[len-1U] == '\r' ) --len;
       tmp.resize(len);
       return tmp;
    }
    
    String datum( void ) {
       time_t ti; time(&ti); struct tm* ti2 = localtime(&ti);
       char buf[100];
       strftime( buf, sizeof(buf), "%Y%m%d", ti2 );
       return String( buf );
    }
    
    String zeit( void ) {
       time_t ti; time(&ti); struct tm* ti2 = localtime(&ti);
       char buf[100];
       strftime( buf, sizeof(buf), "%H%M%S", ti2 );
       return String( buf );
    }
    
    void buchungen_erfassen( void ) {
       FILE* fp = fopen( dateiname.c_str(), "a" );
       if ( fp == 0 ) { fprintf( stderr, "Datei kann nicht geoeffnet werden!\n" ); return; }
       Datensatz satz;
       bool satz_ok = false;
       for (;;) {
          printf( "Auszahlmodus [BAR]: " ); fflush(stdout);
          String eing = eingabe_lesen();
          if ( eing == "BAR" || eing == "" ) satz.Auszahlmodus = BAR;
          printf( "Betrag: " ); fflush( stdout );
          eing = eingabe_lesen();
          satz.Betrag = atof( eing.c_str() );
          printf( "Buchungstyp [AUSZAHLUNG]: " ); fflush(stdout);
          eing = eingabe_lesen();
          if ( eing == "AUSZAHLUNG" || eing == "" ) satz.Typ = AUSZAHLUNG;
          satz.Datum   = atol( datum().c_str() );
          satz.Uhrzeit = atol( zeit().c_str() );
          satz.speichern( fp );
          printf( "Weiter? J/[N]: " ); fflush(stdout);
          eing = eingabe_lesen();
          if ( eing == "n" || eing == "N" || eing == "" ) break;
       } 
       fclose( fp );
    }
    
    int main( int argc, char** argv ) {
       for (;;) {
          printf( "Menue:\n------\n(1) Buchungen anzeigen\n(2) Buchungen erfassen\n" );
          printf( "(3) Ende\n\n==> " ); fflush(stdout);
          String eing = eingabe_lesen();
          if ( eing == "1" ) buchungen_anzeigen();
          else if ( eing == "2" ) buchungen_erfassen();
          else if ( eing == "3" ) break;
       }
       return 0;
    }
    

Anmelden zum Antworten