P
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;
}