Datumsexpansion



  • Hallo miteinander! Ich habe folgendes Problem:
    Ich verstehe zwar größtenteils die Sprachelemente von c++, leider fehlt mir die nötige Übung und auch

    das gewisse etwas, was einen Programmierer ausmacht.
    Nun soll ich ein kleines Programm mit grafischer Oberfläche schreiben, welches folgende Funktionen hat:

    Die Datei "In.txt" enthält einen vorgegebenen Text mit mehreren Datumsangaben im Format
    dd.mm.yyyy oder d.m.yyyy bzw. dd.m.yyyy, d.mm.yyyy sowie etliche Datumsangaben in
    einem anderen, "falschen" Format, oder auch generell unmögliche Datumsangaben wie
    37.12.2001. Die Datei soll gelesen werden und nach entsprechenden gültigen Datumsangaben
    durchsucht werden. Wird ein gültiges Datum gefunden, so ist es zu expandieren in der Form:
    Wochentag, dd. Monat yyyy.
    Als Ausgabe soll dann die Datei "Out.txt" den gleichen Inhalt wie "In.txt", nur eben mit dem

    einheitlichen Datumsformat erstellt werden.

    Auf gut Deutsch:
    Vorgabedatum: 07.05.2005 oder 7.5.2005 oder 07.5.2005 oder 7.05.2005
    Ausgabedatum: Samstag, 07. Mai 2005

    Dazu verwenden kann ich folgende Dateien, die aus einem ähnlichen Programm stammen, welches jedoch als

    Datumsangabe nur das Format dd mm yyyy berücksichtigte.

    meindate.cpp

    // ---------------------------- meindate3.cpp -------------------------------
    //
    
    #pragma hdrstop
    #include <condefs.h>
    #include <conio.h>
    #include <iostream.h>
    #include "mylib.h"
    
    //---------------------------------------------------------------------------
    USEUNIT("mylib.cpp");
    //---------------------------------------------------------------------------
    #pragma argsused
    
    int main(int argc, char* argv[])
    {
    //mydate *datum = new mydate;
     f_date *datum = new f_date;
    
    while (1)
    {
    while (!datum->get());
    
    datum->print2();
    cout<<"\nAktuelles Datum: ";
    datum->today();
    datum->print2();
    getchar();
    
    }
    }
    

    mylib.cpp

    //-------------------------------- mylib.cpp --------------------------------
    #pragma hdrstop
    #include <conio.h>
    #include <iostream.h>
    #include "mylib.h"
    #include <dos.h>
    //---------------------------------------------------------------------------
    #pragma package(smart_init)
    mydate::mydate(void):tag(1),monat(1),jahr(2000)
    {}
    
    void mydate::print(void)
    {
    umwandeln();
    cout<<tag<<"."<<monat<<"."<<jahr<<endl;
    }
    
    int mydate::get(void)
    {
    int check;
    
    cout<<"Datum eingeben (dd mm yyyy): ";
    cin>>ws;
    cin>>tag>>monat>>jahr;
    
    if (0 <= tag && tag <= 31)
         {}
    else {
         cout<<"Der eingegebene Tag ist falsch.\n";
         check = 1;
         }
    
    if ((tag > 28) && (monat == 2 ) && ((jahr%4 !=0 ) || (jahr%100 == 0) && (jahr%400 !=0)) )
         {
         cout<< "Jahr ist kein Schaltjahr! "<< endl;
         check = 1;
         }
    
    if ((tag == 0) && (monat == 0) && (jahr == 0))
         {
         check = 1;
         }
    
    if ((tag > 31) || (tag <= 0) || (tag >29) && (monat == 2))
         {
         cout<< "Falsches Tagesformat ! "<< endl;
         check = 1;
         }
    
    if (1 <= monat && monat <= 12)
         {}
    else {
         cout<<"Der eingegebene Monat ist falsch.\n";
         check = 1;
         }
    
    if (jahr >= 1900)
         {}
    else {
         cout<<"Das eingegebene Jahr ist falsch.\n";
         check = 1;
         }
    
    if (tag == 0 && monat == 0 && jahr == 0)
        exit(1);
    
    if (check == 1)
         return 0;
    else return 1;
    
    }
    
    void mydate::today(void)
    {
    struct date d;
    
       getdate(&d);
       tag = d.da_day;
       monat = d.da_mon;
       jahr = d.da_year;
    }
    
    void mydate::umwandeln(void)
    {
      unsigned int ntage;
      int nzykl;
      int njahre;
      int wtag;
      int yy;
    
      yy= jahr-1900;
    
      ntage=(unsigned)(30.41666666*(monat-1))+tag;
    
      if(monat==2)
      ++ntage;
    
      if((monat>2)&&(monat<8))
      --ntage;
    
      if((yy%4==0)&&(monat>2))
      ++ntage;
      nzykl=yy/4;
      ntage+=1461*nzykl;
      njahre=yy%4;
      if(njahre>0)
      ntage+=365*njahre+1;
      if(ntage>59)
      --ntage;
      wtag=ntage%7;
      if (wtag == 1)
          cout<<"Montag, der ";
      if (wtag == 2)
          cout<<"Dienstag, der ";
      if (wtag == 3)
          cout<<"Mittwoch, der ";
      if (wtag == 4)
          cout<<"Donnerstag, der ";
      if (wtag == 5)
          cout<<"Freitag, der ";
      if (wtag == 6)
          cout<<"Samstag, der ";
      if (wtag == 0)
          cout<<"Sonntag, der ";
    //  return(wtag);
    }
    
    void f_date::month(void)
    {
      switch (monat)
      {
            case 1:
                    cout<< " Januar ";
                    break;
            case 2:
                    cout<< " Februar ";
                    break;
            case 3:
                    cout<< " Maerz ";
                    break;
            case 4:
                    cout<< " April ";
                    break;
            case 5:
                    cout<< " Mai ";
                    break;
            case 6:
                    cout<< " Juni ";
                    break;
            case 7:
                    cout<< " Juli ";
                    break;
            case 8:
                    cout<< " August ";
                    break;
            case 9:
                    cout<< " September ";
                    break;
            case 10:
                    cout<< " Oktober ";
                    break;
            case 11:
                    cout<< " November ";
                    break;
            case 12:
                    cout<< " Dezember ";
                    break;
      };
    }
    
    void f_date::print2(void)
    {
    umwandeln();
    cout<<tag<<".";
    month();
    cout<<jahr<<endl;
    }
    

    mylib.h:

    //--------------------------------- mylib.h ---------------------------------
    #ifndef mylibH
    #define mylibH
    //---------------------------------------------------------------------------
    
    class mydate
    {
      public:
            int tag;
            int monat;
            int jahr;
            mydate(void);
            mydate(int,int,int);
            ~mydate(void)
            {
            }
            void print(void);
            void today(void);
            int get(void);
            void umwandeln(void);
            int returnmonth(void);
    };
    
    class f_date:public mydate
    {
      public:
            void month(void);
            void print2(void);
    };
    #endif
    

    Ich dachte an eine Verwendung der Funktionen isdigit und ispunct aus der Bibliothek ctype.h

    Ich hoffe, ihr könnt mir helfen, da ich alleine mit Büchern, www und meinem vorhandenem Wissen nicht in

    der Lage bin dieses zu realisieren.

    Viele Grüße und besten Dank im Voraus!



  • Zu diesen Datumgültigkeitsprüfungs-Geschichten gibt es schon mehr als einen Thread. Z. B. den hier:
    http://www.c-plusplus.net/forum/viewtopic-var-t-is-101078-and-start-is-0.html

    Vielleicht hilft dir das ja schon was, hab nur den halben Post gelesen.



  • Okay danke!
    Ist natürlich blöd von mir diese ganze Aufgabe hier zu formulieren, aber ich finde nichtmal einen richtigen Ansatz, wie ich anfangen soll.



  • Warum nicht einfach die vorhandene Routine nutzen und die '.' durch ' ' ersetzen? (aus dem String "12.10.2005" wird "12 10 2005" und dann kannst Du ja die vorhandene Routine nutzen)



  • niemand schrieb:

    Warum nicht einfach die vorhandene Routine nutzen und die '.' durch ' ' ersetzen? (aus dem String "12.10.2005" wird "12 10 2005" und dann kannst Du ja die vorhandene Routine nutzen)

    Ja stimmt, das ist ne klasse Idee!

    Nur folgendes Problem: In der Textdatei, welche eingelesen wird, stehen ja auch Punkte, die nicht zu einem Datum gehören. (z.B. zwischen zwei Sätzen)
    Diese würden dann Auch ersetzt.

    Ausserdem müsste ich dann noch bei nem Datum wie z.B. 2.5.2005 noch Nullen vor den Tag und Monat setzen, aber das dürfte ja zu machen sein.

    Jedenfalls Danke für den Ansatz, ich werde mein Köpfchen mal bemühen 🙂



  • Soweit ich das sehe, benötigt Deine Routine keine führenden 0.

    Was ist denn das für eine Datei? Um Deine Routine zu nutzen, musst Du das Datum schon erkannt haben. Ist das denn eine Tabelle oder so was, wo das Datum immer in der gleichen Spalte steht, oder ist es ein echter Fliesstext?

    In letzterem Fall gehst Du Zeichen für Zeichen durch und prüfst, ob das Zeichen eine Ziffer ist. Wenn es eine Ziffer ist, merkst Du Dir, dass Du ein mögliches Datum hast. Dann prüfst Du das nächste Zeichen. Das muss eine Ziffer oder ein Punkt sein. Ist eine Ziffer fügst Du es der bisherigen Ziffer hinzu und gehst zum nächsten Zeichen. Das muss ein Punkt sein. Die gefundenen Ziffern (eine oder zwei) müssen dann <= 31 sein. Trifft irgendeine Bedingung nicht zu (die verhindert das es ein Datum ist), setzt Du Dein Flag für das "mögliche Datum" zurück und gehst weiter im Text. In diesem Fall benötigst Du die Routine aus Deinem ersten Posting praktisch nicht (ausser vielleicht um ähnliche Fehlermeldungen auszugeben).



  • niemand schrieb:

    Soweit ich das sehe, benötigt Deine Routine keine führenden 0.

    Da gebe ich Dir recht, jep. 🙂

    Es ist ein richtiger Fließtext mit Zeilenumbrüchen. Ich paste mal den Anfang:

    Dies ist die 1. Zeile der Datei In.txt. Sie enthaelt kein Datum.
    Hier die 2. Zeile mit Datum 01.01.1901
    Dritte Zeile ohne Datum.
    4. Zeile mit Datum 1.01.1955
    1.1.1966
    Diese Zeile ist die 6. und hat kein Datum.
    

    Deine 2te Lösungsmethode gefällt mir, an soetwas ähnliches habe ich schon gedacht. Ich denke, ich werde das so machen, hoffe dabei nur dass ich es umsetzen kann 😉

    Ich denke ich speichere, wie auch in meiner gepasteten Routine oben, Tag, Monat und Jahr einzeln ab und kontrolliere diese auch wie oben in mylib.cpp ob es ein gültiges Datum ist.



  • @niemand
    meinst du, es wäre auch folgender ansatz möglich:
    - zeile aus datei lesen
    - diese zeile in "worte" aufteilen, indem ich nach leerzeichen suche
    - diese worte wiederrum aufteilen, indem ich nach punkten suche
    - wenn ein zerlegtes wort dann 3 bestandteile hat und dabei die anzahl der teile stimmt (bei tag und monat also 2, bei jahr 4) kann ich tag,monat und jahr an die vorhandene routine übergeben.

    was hältst du von der lösung?
    hast du eine ahung, wie man zeilen aufteilen kann? in VB-Script gibt es da sowas wie "Split"?

    Danke!



  • na das ist doch ein prima ansatz!
    guck dir mal die funktionen strstr und strtok an...



  • ahja strstr ist auch nicht schlecht! habe es aber inzwischen mit strtok und ein paar if-anweisungen so hingebracht dass ich tag, monat und jahr herausfiltere 🙂
    der rest sollte mit der oben gepasteten routine machbar sein.

    ... jedenfalls ist es genial, solche foren zu haben, wo jedem schnell und kostenlos geholfen wird 👍


Anmelden zum Antworten