kleines verwaltungsprogramm für wareneingang



  • danke für den tipp es funktioniert!!! 👍 dafür ist wieder ein neues problem aufgetaucht ^^

    und zwar will ich jedes Eingansdatum, zu welchem ein warenbestand vorliegt in eine Textdatei "Eingangsdatum.txt" abspeichern. hat auch soweit funktioniert, nur dass mir das programm manchmal mehrmals das gleiche datum reinkopiert hat, nun will ich das umgehen und lasse zuerst alle einträge in dieser textdatei mit dem aktuellen datum vergleichen. danach wird das aktuelle datum abgespeichert und zwar nur dann, wenn es noch nicht in "Eingangsdatum.txt" vorliegt.
    das programm startet auch , doch jedes mal wenn die funktion aufgerufen wird,geht es im programm nicht weiter..ich kann nichts mehr eingeben, es ist dann nur ein blinkender cursor da...versteh nicht, wieso das nicht funktioniert, bei dem auslesen hat der vergleich der stings mit der gleichen Vorgehensweise geklappt.

    der Quellcode dazu:

    /*--------------------------ABSPEICHERN VON JEDEM DATUM-----------------------*/
    
    float speichern_eingangsdatum ()
    {
         eingangsdatum(); /* Funktion muss aufgerufen werden, sonst wird Das Eingangsdatum nicht im String temp abgespeichert!!*/
         char datum [255];
         int vergleich;
    
         bool vorhanden;
         vorhanden = false;
    
         FILE *fp;
         fp = fopen ("Eingangsdatum.txt","a");
         if (NULL==fp)
               printf (" Fehler beim Oeffnen\n"); /* Wenn kein Speicherplatz vorhanden ist */
         else 
          {    
              while (!feof(fp))
              {
                    fgets (datum, sizeof(datum),fp);
    
                    if (datum[strlen(datum)-1]=='\n')
                    datum[strlen(datum)-1] = 0;
    
                    vergleich = strcmp (datum,temp);
    
                    if ( vergleich == 0)  
                    {
                         return 0;
                         vorhanden = true;
                    }
                }
             if (!vorhanden)
             {
             fprintf (fp,"\n%s",temp);
             }
             fclose(fp);
         }
    return 0;
    }
    

    Hoff es fällt irgendjemandem was auf
    Danke schonmal für Lösungsvorschläge!!



  • hab den Fehler mittlerweile selber gefunden, es liegt an :

    fp = fopen ("Eingangsdatum.txt","a");

    wenn ich dass "a" gegen ein "r" austausch, funtioniert das ganze wieder!!!



  • die menüpunkte 1 und 2 habe ich nun komplett abgearbeitet, komm jetzt aber bei dem Punkt Tagesstatistiken überhaupt nicht weiter.
    Unter diesen Menüpunkt, frage ich zunächst ab, von welchem Datum die Tagesstatistik ausgegeben werden soll und öffne die entsprechende Tagesdatei zum auslesen....das klappt soweit.

    nun will ich die Datei durchgehen und z.B. alle Preise zusammenaddieren und dann ausgeben. hab mir überlegt das ganze mit einer einfach verketteten liste zu machen, aber irgendwie fehlt mir da komplett der einstieg und ich weiss überhaupt nicht, wie ich damit anfangen soll. Würd mich freuen, wenn mir jemand weiterhelfen kann.



  • nun will ich die Datei durchgehen und z.B. alle Preise zusammenaddieren und dann ausgeben. hab mir überlegt das ganze mit einer einfach verketteten liste zu machen

    Brauchst du gar nicht. Für sowas wie die Summe aller Preise reicht eine Zahlen-Variable, in der du die Summe zusammenbaust. Die ist am Anfang 0, und dann läufst du zeilenweise über die Datei und zählst den Preis dazu.

    aber irgendwie fehlt mir da komplett der einstieg und ich weiss überhaupt nicht, wie ich damit anfangen soll.

    Listen sind ganz einfach. Die bieten sich dort an, wo man deshalb kein Array nehmen will, weil man nicht weiß, wie lang das Ding werden wird. Wenn du weißt, was Zeiger und Strukturen sind, und wie man dynamisch Speicher anfordert, dann wirst du das folgende verstehen:

    struct node {
        int data;
        struct node *next;
    }
    
    globale_liste = NULL;
    
    void neues_element_an_den_listenanfang()
    {
        struct node *temp = malloc(sizeof(*temp));
    
        if (!temp) {
            // Fehler - kein Speicher mehr da
        }
    
        temp->next = globale_liste;
        globale_liste = temp;
    }
    
    void globale_liste_freigeben()
    {
        struct node *temp = globale_liste;
    
        for ( ; temp; temp = temp->next)
            free(temp);
    }
    

    Aber eigentlich weißt du ja, wie lang das Ding werden wird, weil du vorher die Zeilen in der Datei zählen kannst. Wenn du das machst, kannst du auch ein Array verwenden.

    EDIT: Code ist zwar nur ein Prinzip-Schema, war aber trotzdem verbuggt.



  • der quellcode hilft mir irgendwie nicht weiter....

    ich weiss zwar, wie ich die Summe aller Preise bilde, aber ich weiss nicht, wie ich die datei durchgehen soll und auf die anzelnen Preise zugreifen kann, um sie anschließend zusammenzuzählen .
    ich muss dazusagen, dass ich beim abpeichern aller Daten keine structur und keine einfach verkettete liste benutz habe.

    beim abspeichern habe ich einfach eine datei zum anhängen geöffnet und dort meine eingabe jedes mal ans ende gehängt.

    Die abgespeichten Daten schauen in der Textdatei folgendermaßen aus:

    Artikelname: Kugellager
    Zulieferer: SKF
    Anzahl: 100 Stueck
    Stueckpreis: 19.21 Euro
    angenommen von: Hans Wurst

    Artikelname: Bleche
    Zulieferer: SKF
    Anzahl: 10 Stueck
    Stueckpreis: 2.34 Euro
    angenommen von: Michael Mustermann

    Artikelname: Kugellager
    Zulieferer: FAG
    Anzahl: 15 Stueck
    Stueckpreis: 23.43 Euro
    angenommen von: Hans Wurst

    hoff, dass damit mein problem besser beschrieben ist



  • ch muss dazusagen, dass ich beim abpeichern aller Daten keine structur und keine einfach verkettete liste benutz habe.

    Das hatte ich auch nur geschrieben, weil mir gerade langweilig war und du danach gefragt hattest.

    hoff, dass damit mein problem besser beschrieben ist

    In der Tat. Üblicherweise macht man solche Dateien so, daß jeder Geschäftsfall in einer Zeile steht, also zB so:

    Kugellager;SKF;100;19.21;Hans Wurst
    ...
    

    Und das hatte ich angenommen, als ich "zeilenweise" sagte.

    Aber in jedem Fall wirst du eine Funktion haben wollen, die aus einer offenen Datei den nächsten Datensatz herausliest (so wie getc() das nächste Zeichen liest). Da bietet sich wieder mal eine Struktur für einen Datensatz an, weil die Funktion ja mehrere Dinge zurückgeben muß, und am einfachsten packt man die in eine Struktur.

    Mein Datei-Format wäre etwas einfacher zu parsen (siehe man: strtok). Aber auch bei deinem sollte es nicht schwer sein, du musst eben zeilenweise Strings einlesen, und die "Fix-Felder" wie "Artikelname:" ingorieren. Dazu gibt's man: fgets (man: scanf ist böse).

    Allgemein empfehle ich, das Dateiformat weniger menschen-lesbar zu machen, und mehr darauf zu achten, daß das Einlesen einfach ist.



  • danke für die schnelle antwort!

    also das abspeichern in der Textdatei hab ich absichtlich so strukturiert, damit man die Möglichkeit hat, am Ende des Tages die Wareneingänge auszudrucken.

    aber ich probier jetzt mal dein Lösungsvorschlag aus und speicher die zusammengehörenden Werte Zeilenweise ab.

    noch zum Verständnis:

    Kugellager;SKF;100;19.21;Hans Wurst
    Kugellager;FAG;15;23.43;Hans Wurst
    

    müsste ich in diesem Fall auf token4 zugreifen, um meine Preise auszulesen?

    Hab hier mal deine Idee versucht auf die schnelle umzusetzten, habs aber noch nicht ausprobiert:

    //globale Variable: 
    
    float gesamtkosten = 0;
    
    //lokal:
    
    char string [255];
    char trennzeichen [255] = ";";
    char *wort;
    float preis = 0;
    
    while (!feof(fp)) 
    {
      fgets(string,sizeof(string),fp);
      int i = 1;
      wort = strtok(string, trennzeichen);
      while(wort != NULL) 
      {
        if (wort == 4);
         {
          preis = atof(wort);
          gesamtkosten = gesamtkosten + preis;
         }
        wort = strtok(NULL, trennzeichen); 
      }
    
    }
    

    hab mich nach http://de.wikibooks.org/wiki/C-Programmierung:_Strings#strtok gerichtet.

    bin ich damit auf dem richtigen weg, oder tapp ich immer noch im dunkeln? ^^



  • strtok ist doch voll der schrott. mach das doch mit fscanf und fprintf



  • hm wüsste nicht, wie ich das mit fscanf und fprintf machen könnte...
    wenn du mir einen konkreteren Lösungsvorschlag geben könntest, wär ich dir dankbar 🙂



  • TRENN DIE WERTE DURCH LEERZEICHEN UND LIES DANN EINFACH MIT fscanf ein und schreib die datei entsrpechend mit fprintf. solche strtok und fwrite frickeleien und parsereien gehen meist in die h0se

    sroyy for caps



  • bin ich damit auf dem richtigen weg, oder tapp ich immer noch im dunkeln?

    So hatte ich mir das vorgestellt. (Hab's aber nicht getestet)
    Falls du in Zeile 19 i statt wort gemeint hast.

    also das abspeichern in der Textdatei hab ich absichtlich so strukturiert, damit man die Möglichkeit hat, am Ende des Tages die Wareneingänge auszudrucken.

    Das kriegst du auch so hin.
    ZB mit Excel, dafür musst du die Datei dann nur mit der Endung .csv versehen.
    CSV ist auch außerhalb von Office weit verbreitet.



  • hi Leute,

    hab jetzt wieder etwas, woran ich mich aufgehangen habe.
    Und zwar will ich beim Einlesen von dem Stückpreis alle möglichen falschen Eingaben abfangen..und den Anwender solang was eingeben lassen, bis der Stückpreis die richtige Form hat.

    Zunächst will ich den Anwender solange was eingeben lassen, bis er eine zahl eingibt:

    do
    {
      printf("Stueckpreis:");
      gets(pr); 
    
      i=0; a=pr[0];
      while (a!= '\0') 
      {
        if ((a>='0') && (a<='9'))
        {
        c = 1;  
        }     
        else
        {
        c = 0;
        }
        a=pr[++i];
       }
    
    }while ( c == 0);
    

    Mit dieser Schleife kann ich folgende Falscheingaben abfangen:

    fünfzig
    12asdfkl

    Das Problem an der schleife ist jedoch, das Eingaben wie z.B. "alöksdf123.30" (weil am ende eine Zahl steht) oder "12,50" nicht abgefangen werden können!

    Oder jedes mal, wenn ich "12,50" statt "12.50" eingebe, wird mir der Stückpreis mit "12.00" in der Textdatei abgespeichert!

    Was kann ich dagegen tun ? Gibt es einen Standartbefehle, mit denen ich die Fehler abfangen kann ? Hoffe es kann mir jemand bei den zwei Sachen helfen.

    danke schonmal !



  • Zunächst will ich den Anwender solange was eingeben lassen, bis er eine zahl eingibt:

    Der Stückpreis ist wahrscheinlich keine ganze Zahl, also willst du eine Gleitkommazahl abfragen.
    Du könntest man: strtof und man: strtold verwenden:

    #include <stdio.h>
    #include <stdlib.h>
    
    int main (void)
    {
      char *start = "3.14159Xasdf", *last = NULL;
      double zahl = 0.0;
    
      zahl = strtold(start, &last);
    
      printf("Zahl: %f\nnaechstes Zeichen: %x (%c)\n", zahl, *last, *last);
    
      return 0;
    }
    

    Wenn das nächste Zeichen nicht Null ist, dann ist nach der Zahl noch Rauschen (in dem Fall 'X').



  • b_wise schrieb:

    do
    {
      printf("Stueckpreis:");
      gets(pr);
    

    Über man: gets(3) aber:

    gets(3) schrieb:

    Never use gets(). Because it is impossible to tell without knowing the
    data in advance how many characters gets() will read, and because
    gets() will continue to store characters past the end of the buffer, it
    is extremely dangerous to use. It has been used to break computer
    security. Use fgets() instead.

    Also wenn du pr im Kontext definiert hast

    fgets(pr, sizeof(pr), stdin)
    // statt
    gets(pr);
    

    Sonst musst du dir noch die Länge merken.



  • b_wise schrieb:

    if ((a>='0') && (a<='9'))
    {
    c = 1;  
    }    
    else
    {
    c = 0;
    }
    

    😕

    c = (a>='0') && (a<='9');
    

    🙂



  • hm das hilft mir alles nicht weiter 😞



  • Und warum soll ich raten? 😉
    Wo bist du denn steckengeblieben?



  • servus,

    ich will nur reelle Zahlen einlesen, aber irgendwie kann ich mit den zwei funktionen nur ganze zahlen einlesen...weiss einfach nicht mehr wie ich das lösen soll

    void einlesen_stueckpreis()
    {
    
        printf("Stueckpreis: ");
        gets(stueckpr);
        kontrolle_eingabe_stueckpreis(stueckpr);
    
    }
    
    int kontrolle_eingabe_stueckpreis(char stueckpreis[])
    
    {    
    
    char a;
    int i = 0, c = 0;
    
    do 
     {
    
      a = stueckpreis[0];
      while (a!= '\0') 
      {
        if ((a>='0') && (a<='9') && '.')
        {
        c = 1;  
        }     
        else
        {
        printf("\nEs ist nur die Einganbe von Reellen Zahalen gueltig!\n\n");
        einlesen_stueckpreis();
        }
        a=stueckpreis[++i];
       }
    
     }while ( c == 0); 
    
    return 0;
    
    }
    

    danke schonmal für lösungsvorschläge 🙄



  • Dein Code sieht eher wenig vertrauenswürdig aus:

    einlesen_stueckpreis ruft kontrolle_eingabe_stueckpreis auf, und umgekehrt, bist du sicher,
    daß da nicht noch eine Endlosschleife rauskommt?

    ((a>='0') && (a<='9') && '.')
    

    '.' ist immer wahr. Wahrscheinlich meinst du

    ((a>='0') && (a<='9') || a=='.'))
    

    In rellen Zahlen sind BTW noch mehr Zeichen als Ziffern und der Punkt zulässig.
    Zb + und -, aber auch E und e. Etwas vergessen? Egal, denn:

    ~mngbd schrieb:

    Du könntest man: strtof und man: strtold verwenden

    Das hatte ich gesagt, und alles, was dir dazu eingefallen ist, war:

    hm das hilft mir alles nicht weiter 😞

    Also mein Vorschlag für Gleitkommazahlen statt ganzen Zahlen:

    int kontrolle_eingabe_stueckpreis(char stueckpreis[])
    {
        char *last = NULL;
    
        if (strtold(stueckpreis, &last) == 0.0 && stueckpreis == last)
            return 1;  // stueckpreis ist keine gültige Zahl
        else
            return 0;  // stueckpreis ist gültig
    }
    

    Wenn du mir weiterhin nicht sagst, warum dir das nicht weiterhilft, wird mir die Lust vergehen, dir zu helfen.


Anmelden zum Antworten