Beim Matching die vordere in eine Variable speichern in C

Sergei

Mitglied
Hallo, liebe Users, ich hoffe ich bekomme hier eine Hilfe.
Die File besteht aus 10 tausend Zeilen,
Ich lese das Zeilenweise und suche zwei Wörter
1-te "Lukas Maly gekommen"
2-te "Lukas Maly weg"

bei der Suche gibt mir aus:

11.02.2017 Lukas Maly gekommen
12.02.2017 Lukas Maly gekommen
13.02.2017 Lukas Maly gekommen
13.02.2017 Lukas Maly weg

14.02.2017 Lukas Maly gekommen
14.02.2017 Lukas Maly weg

15.02.2017 Lukas Maly gekommen
16.02.2017 Lukas Maly gekommen
16.02.2017 Lukas Maly weg

-----------------------------------------------------------------------------------------------------
ich muss jetzt bei der Zeile die nacher keine "Lukas Maly weg" steht eine Fehlermeldung ausgben zB:
11.02.2017 Lukas Maly gekommen --vergessen aussustempelln
12.02.2017 Lukas Maly gekommen --vergessen aussustempelln
15.02.2017 Lukas Maly gekommen --vergessen aussustempelln

wie bekomme ich zugriff auf die vordere Strings?
Für jede Hilfe werde ich sehr dankbar. ich hoffe auf Ihre Antwort

Das ist mein Kod bis jetzt http://pastebin.com/jVL905FJ

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void) {
FILE *pf;
char line1[100];

char * sub1;
char * sub2;
int countgw1 = 0;
int countgw2 = 0;

char filename[50] = {"/home/alt/2017-Projekte//Lukas"};
const char suchstring1[50] = "Lukas Maly gekommen";
const char suchstring2[50] = "Lukas Maly weg";

printf("=============================================================================\n");
pf = fopen(filename, "r"); // öffne zum lesen
if (pf != NULL) {
while (!feof(pf)) { // lese bis Ende des Files
fgets(line1, 120, pf);
if (strstr(line1, (suchstring1)) != NULL) { // wenn erstes Wort existiert
sub1 = line1; // dann speichere in sub1
countgw1++;
printf("%2d-Gekommen: %s\n", countgw1, sub1);

if ((strstr(line1, (suchstring1)) != NULL)&&(strstr(line1, (suchstring1)) != NULL)) {
// printf(" AnD: %s\n", sub1);
}
}
if (strstr(line1, (suchstring2)) != NULL) {
sub2 = line1;
countgw2++;
printf("%2d-Wegegang: %s\n", countgw2, sub2);
}
}
} else {
printf("Could not open the file.\n");
abort();
}
}
 

Anhänge

  • lukasN.txt
    1,8 KB · Aufrufe: 3
Zuletzt bearbeitet:

cwriter

Erfahrenes Mitglied
Hi

wie bekomme ich zugriff auf die vordere Strings?
Für jede Hilfe werde ich sehr
Dateien sind sequentielle Container, tatsächlich sind sie sehr ähnlich zu allen Tapes/Magnetbändern.
D.h. du kannst mit fseek() immer auf Vergangenes zugreifen - aber ähnlich wie das Zurückspulen bei Kassetten (falls du das noch kennst) ist das Zurückgehen in einer Datei sehr langsam.

Aber du musst auch gar nicht in die Vergangenheit gehen, wenn du sie schon erlebt hast.

Was du willst, lässt sich leicht mit einem Online-Algorithmus (also einem Algorithmus, der nur O(1) (siehe Landau-Notation) Speicher braucht.
Sagen wir, du findest einen Check-In für einen gegebenen (eindeutigen) Namen.
Dann setzt du eine boolsche Variable auf true (oder in altem C: Einen int auf 1).
Dann suchst du weiter. Falls du direkt danach auf einen Check-Out derselben Person triffst, setzt du die online-Variable auf false (0).
Nun: Falls die Variable 1 ist und ein Check-In stattfindet, dann besteht ein Fehler: Die Person ist ja schon hier.
Dasselbe gilt, wenn die Variable 0 ist und ein Check-Out stattfindet.

Dieser Algorithmus läuft in O(n) und ist daher optimal.

Zu deinem Code (Code in Zukunft bitte mit Codetags ([code=c][/code]) einfügen):
Der Code ist kreuzfalsch.
line1 ist 100 Bytes gross, du sagst fgets() aber, dass es 120 Bytes einlesen darf. Diese 20 Bytes marodieren dann in deinem Arbeitsspeicher und machen alles kaputt (Segfault).
feof() sollte nicht verwendet werden, fgets() reicht (wenn das Ende erreicht ist, gibt fgets NULL zurück).
Das fclose() fehlt.
Beim Suchen nach dem ersten String verundest du dasselbe (A&&A == A). (Kein Fehler, aber unschön).
In sub1 wird nichts gespeichert. sub1 zeigt nur auf line1 (Wenn ich dir "Hauptbahnhof" auf einen Zettel schreibe, ist nicht der Hauptbahnhof auf dem Zettel, sondern ein Verweis darauf).
Die Klammern um die Suchstrings sind überflüssig.

(Der Code "läuft", ist aber unschön und vor allem unsicher. Versuche doch als Übung, das Einlesen der Zeilen mit der Loopbedingung zu verknüpfen.)

Gruss
cwriter
 
Zuletzt bearbeitet:

Sergei

Mitglied
(Der Code "läuft", ist aber unschön und vor allem unsicher. Versuche doch als Übung, das Einlesen der Zeilen mit der Loopbedingung zu verknüpfen.)
 

Sergei

Mitglied
Guten Morgen cwriter,

Danke danke sehr für all die Ratschläge, du hast meine Augen aufgemacht, ich habe vorher diese Fehler nicht gewusst, ich war nur zufrieden damit das alles funktionniert, ich bin noch Anfänger, ich versuche deine Ratschläge zu folgen und die Programme zum laufen zu bringen, aaaaai so was ich denke ich schaffe nicht es klingt alles so kompliziert aus :confused::confused::confused::mad:.
mit freundlichen Grüss Sergei
 

cwriter

Erfahrenes Mitglied
so was ich denke ich schaffe nicht es klingt alles so kompliziert aus :confused::confused::confused::mad:.
War das eine Frage?

Das Einlesen mit fgets() ist wesentlich einfacher als mit feof(), das sollte eigentlich klar sein.
Tipp: while(fgets(buffer, buffersize, file)) { /* Buffer bearbeiten */}
Zum Algorithmus: Was kommt dir daran kompliziert vor?

Gruss
cwriter
 

Sergei

Mitglied
C:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void) {
    FILE *pf;
    int maxZ = 100;
    char line1[maxZ];

    int countgw1 = 0;
    int countgw2 = 0;

    int bool1 = 0;
    int bool2 = 0;

    char * sub1;
    char * sub2;

    char filename[50] = {"/home//Lukas"};
    const char suchstring1[50] = "Lukas Maly gekommen";
    const char suchstring2[50] = "Lukas Maly weg";

    printf("=============================================================================\n");
    pf = fopen(filename, "r"); // öffne zum lesen
    if (pf != NULL) {
        while (fgets(line1, maxZ, pf)) { // lese bis Ende des Files        
            if (strstr(line1, (suchstring1)) != NULL) { // wenn erstes Wort existiert
                bool1 = 1; // dann boolean soll 1 sein
                countgw1++;
                if (bool1 == 1) { // wenn boolean 1 ist dann zeige
                    sub1 = line1;
                }
            }
            if (strstr(line1, (suchstring2)) != NULL) {
                bool2 = 1;
                countgw2++;
                if (bool1 == 1) {
                    sub2 = line1;
                }
            }
        }
    } else {
        printf("Could not open the file.\n");
        abort();
    }
    if (countgw1 != countgw2) {
        int ung = countgw1 - countgw2;
        printf("%d mal vergessen auszustempelln\n", ung);

    } else {
        printf("immer ausgestemmpelt");
    }
    fclose(pf);
}
 

Sergei

Mitglied
diese Tage wo er vergessen hat sich auszustempelln anzeigen, alles andere ist unwichtig,
C:
 if((bool1==1)&&(bool2==0)){ // dann das heiss gekommen gekommen kommt zwei mal
        printf("%s", sub1);
    }
ich denke ich muss so was einfügen wo kann ich das machen
 

cwriter

Erfahrenes Mitglied
Hi

Dein fclose() ist zu weit aussen (fclose() sollte in der Verzweigung file != NULL stehen; denn falls die Datei nicht geöffnet werden konnte, kannst du sie auch nicht schliessen).

Des weiteren brauchst du nur einen bool-Wert (bzw. einen pro Person. Da du nur eine Person hast: Einen Wert).

Deine sub1 = line1 brauchst du eigentlich nicht (hat ja keinen Effekt).
Da auf einer Zeile nur einer der beiden Suchstrings vorkommen kann, würde ich ein if-else if (und kein if-if) machen.

diese Tage wo er vergessen hat sich auszustempelln anzeigen, alles andere ist unwichtig,
C:
           if (strstr(line1, (suchstring1)) != NULL) { // wenn erstes Wort existiert
                if(bool1 == 1)
                {
                      //Fehler, war eingecheckt und kommt nochmals
                      printf("Fehler bei Ausdruck: \"%s\": Anwesende Person angekommen\n", line1);
                }
                bool1 = 1; // dann boolean soll 1 sein
                countgw1++;
            }
            else if (strstr(line1, (suchstring2)) != NULL) {
                if(bool1 == 0)
                {
                    //Fehler, ging, ohne dagewesen zu sein (Diesen Fall willst du ja nicht behandeln.
                }
                bool1 = 0; //Ging, also nicht mehr da
                countgw2++;
            }

Gruss
cwriter
 

Sergei

Mitglied
Hi cwriter,
Man ich bin bereit deine Füsse zu küssen ;)
ich versuche das zu lösen seit Tagen und du hast das in paar Minuten gelöst. Du bist mein Kumir ab jetzt :)
Herzlichen Dank !!!!!!!!!!
Grüss Serg
 

Sergei

Mitglied
UUUUUUppppppssss

es werden falsche Tage angezeigt es sollte folgende Tage sein

11.02.2017 Lukas Maly gekommen --vergessen aussustempelln
12.02.2017 Lukas Maly gekommen --vergessen aussustempelln
15.02.2017 Lukas Maly gekommen --vergessen aussustempelln