Datei-Auslese eingrenzen



  • Hallo beisammen,

    Erstmal kurz zu mir: Ich bin Anfänger in C, habe mit der Seite http://www.c-programmieren.com/C-Lernen.html die Grundlagen gelernt und möchte sie nun anwenden, wer hätt's gedacht.

    Mein Problem:
    Ich habe eine Textdatei vollständig mit while( fgets() !=0) ausgelesen und sie in einen String gepackt. Jede Zeile ist gleich aufgebaut, zuerst kommt ein Wort, dann das Zeichen '|', dann eine 2- oder 3-stellige Nummer und ein Absatz in die nächste Zeile.
    Ich möchte nun nach diesem einen Wort (dass ich vorher mit gets() manuell definiert habe) im String suchen und ausgeben bzw. die ganze Zeile ausgeben.

    Meine bisherigen Versuche:
    Ich habe einen Pointer definiert, der auf die gesuchte Textstelle im String zeigen soll und anschließend ein printf() Befehl um den String testweise auszugeben.

    Ich poste mal den (relevanten) Code:

    FILE *I;
    char Index[100000];
    char Indexname[]={"Index.txt"};
    char *IndexSuchErgebnis;
    char Fachbegriff[20];
    
    I = fopen(Indexname,"r");
    while( fgets(Index, sizeof(Index), I) !=0 )
    IndexSuchErgebnis=strstr(Index, Fachbegriff);   //Fachbegriff soll das Wort sein
    printf("%s",IndexSuchErgebnis);
    fclose(I);
    

    So wie der Code jetzt da steht bekomme ich (null) ausgegeben, soll heißen den gesuchten String gibt's net. Hilfe.
    Danach soll mit strchr() weiter eingegrenzt werden, aber erstmal das eine, dann das andere. Außerdem wenn mir das Verfahren geläufig ist, werde ich's auch anwenden können (hoffe ich).

    Vielen Dank im Vorraus 🙂
    TocToc



  • Ich bin Anfänger in C,

    Willkommen.

    habe mit der Seite http://www.c-programmieren.com/C-Lernen.html die Grundlagen gelernt

    Pech gehabt, Griff ins Klo.
    Alles Deppen dort, wenigstens bist du nicht auf Pfuscher JW reingefallen, so wie die meisten hier.

    Jede Zeile ist gleich aufgebaut,

    Dann nimmt man fscanf. Dabei kann man auch gleich bei der ersten Zeile, auf die das Muster nicht passt abbrechen, d.h. eine Fehlerbehandlung durchführen.

    ich vorher mit gets()

    gets() benutzen nur Deppen, hast du das auch aus deiner "Lehrquelle"?

    anschließend ein printf() Befehl um den String testweise auszugeben.

    Den ganzen String oder nur das Wort? printf ist für die Ausgabe von Wörtern ungeeignet.

    FILE *I;
    char Index[100000];  /* viel zu groß (Stacküberlauf-Gefahr) und absolut unnütz, wenn man fscanf benutzt */ 
    char Indexname[]={"Index.txt"};
    char *IndexSuchErgebnis;
    char Fachbegriff[20];
    
    I = fopen(Indexname,"r");
    while( fgets(Index, sizeof(Index), I) !=0 ) /* hier fehlt die Klammerung "{" */
    IndexSuchErgebnis=strstr(Index, Fachbegriff);
    printf("%s",IndexSuchErgebnis);  /* hier fehlt die Klammerung "}" */
    fclose(I);
    


  • Jo, diese Seite sieht zwar auf den ersten Blick scheinbar zu gebrauchen aus, ist aber wirklich nicht zu empfehlen. Ich hab in den anfängen das C-HowTo (http://www.c-howto.de/) benutzt.



  • Erst einmal danke für die schnelle Antwort 🙂

    Nocheinmal kurz zur Website...ich kam eigentlich relativ gut klar bis zu den Themen Strings/Dateistreams. DA sind mir dann auch Lücken aufgefallen und ich musste woanders suchen. Tja, jetzt bin ich hier. 😃

    Tatsächlich kam gets() im Tutorial gar nicht vor, ich bin zufällig draufgestoßen und fande den Command einfach und praktisch. Wo ist denn der Haken, will mir jemand das vllt nochmal erklären? 😕

    Ich werde jetzt meinen Code einmal überarbeiten und ggf. noch einmal posten. Und ach ja genau, die gesschweiften Klammern habe ich bewusst weggelassen da ich wissen wollte ob es funktioniert 😉 😃

    Viele Dank
    TocToc



  • gets() holt sich soviele chars wie in der zeile sind und schreibt diese in den buffer, auf den der übergebene char-zeiger zeigt. Diese Funktion prüft nicht, ob alle chars in diesen buffer passen (kann sie auch gar nicht, sie weiß durch den char-zeiger ja nur wo er beginnt). Wenn sie nun über seine grenzen hinausschreibt, überschreibt sie andere daten im speicher, was meistens zum Absturz führt.
    fgets() hingegen kannst du die buffergröße mitgeben, sodass nur soviel gelesen wird, wie in den buffer passt (und natürlich wievil in einer zeile steht). Befrag am Besten mal eine Suchmaschine deiner Wahl wie diese Funktion zu benutzen ist 😉



  • Deswegen fande ich es ja so prakrisch weil er genau die Zeile nimmt 😃

    Naja, egal, ich werds ändern danke schön 🙂

    PS: Wie man fget() benutzt weiß ich hab ich dann doch in den meisten Fällen stehen wenn's um ne Datei geht 🙄



  • Ja da hast du recht, hab ich irgendwie übersehen 😉
    Aber der Unterschied ist eben der Sicherheitsaspekt.



  • Hilfe.
    Ich habe das Gefühl, ich habe es noch schlimmer gemacht oder bin mit meiner unglaublichen Inkompetenz zu weit gegangen. 😞

    Abgeänderter Code:

    FILE *I;
    char Indexname[]={"Index.txt"};
    int Counter;
    char C_TEMP[500];
    
    I = fopen(Indexname,"r");
    fseek(I, 2L, SEEK_SET);  //Muss sein, da in der obersten ersten Zeile eine einzelne Nummer steht, dies stellt aber kein Problem da
    for(Counter=0; Counter<200; Counter++)     //Probeweise auf 200 gesetzt
    {
      fscanf(I, "%s\n",&C_TEMP);
      printf(I, "%s\n",C_TEMP);
    }
    fclose(I);
    

    Fehlermeldungen:
    202 7 D:\Dev-Cpp-projects\Datenbanken\Fachbegriffe\Fachbegriff_Datenbank.c [Warning] passing argument 1 of 'printf' from incompatible pointer type [enabled by default]
    1 0 D:\Dev-Cpp-projects\Datenbanken\Fachbegriffe\Fachbegriff_Datenbank.c In file included from D:\Dev-Cpp-projects\Datenbanken\Fachbegriffe\Fachbegriff_Datenbank.c
    378 15 c:\program files (x86)\dev-cpp\mingw64\x86_64-w64-mingw32\include\stdio.h [Note] expected 'const char * __restrict__' but argument is of type 'struct FILE *'

    In meinem Programm gibt es nicht mal eine Zeile 378...!

    Und so sieht das dann in der Konsole aus...:
    Welchen Fachbegriff willst du suchen: Mitose
    └va└va└va└va└va└va└va└va└va└va└va└va└va└va└va└va└va└va└va└va└va└va└va└va└va└va└v
    a└va└va└va└va└va└va└va└va└va└va└va└va└va└va└va└va└va└va└va└va└va└va└va└va└va└va└
    va└va└va└va└va└va└va└va└va└va└va└va└va└va└va└va└va└va└va└va└va└va└va└va└va└va└va
    └va└va└va└va└va└va└va└va└va└va└va└va└va└va└va└va└va└va└va└va└va└va└va└va└va└va└v
    a└va└va└va└va└va└va└va└va└va└va└va└va└va└va└va└va└va└va└va└va└va└va└va└va└va└va└
    va└va└va└va└va└va└va└va└va└va└va└va└va└va└va└va└va└va└va└va└va└va└va└va└va└va└va
    └va└va└va└va└va└va└va└va└va└va└va└va└va└va└va└va└va└va└va└va└va└va└va└va└va└va└v
    a└va└va└va└va└va└va└va└va└va└va└va└va└vaDrücken Sie eine beliebige Taste . . .

    200 Mal dieses komische Zeichen..
    Grässlich und ich weiß nix damit anzufangen. Habe ich falsche Rückgabetypen definiert? 😕



  • STOPP BITTE NICHT ANTWORTEN

    Ich war wirklich grade hart inkompetent.
    Oder warum habe ich ansonsten im printf() Befehl den Datei Pointer dazu gepackt, hm?
    😃 😃 😃 🙄



  • Du verwendest fscanf falsch, fscanf ist gerade kein Ersatz für fgets, deshalb ist es Unsinn, es genauso einzusetzen.
    Baue die eine Datenstruktur auf, die genau deine Zeilenwerte aufnehmen kann, baue die eine Liste davon und fülle diese Liste mit allen Werten aus der Datei.
    Anschließend arbeitest du dann ausschließlich mit dieser Liste, das ist sehr viel einfacher als direkt beim Lesen aus der Datei schon irgendwie was rumzufrickeln.



  • Aber müsste dann nicht für jede Zeile ein Struktureintrag vorhanden sein? Es soll ja eher dynamisch sein, so müsste ich in der Struktur ja jedes Mal manuell einen char String hinzufügen oder hab ich da was falsch verstanden?

    struct Name
    {
    String1;
    String2;
    String3;
    .
    .
    .
    }



  • Wer lesen kann ist klar im Vorteil.
    Ich habe nicht gesagt, du sollst in der struct eine Stringliste aufbauen, sondern eine Liste von struct.
    Das macht man, indem man zuerst mit malloc eine übliche Größe reserviert, und wenn die dann mal nicht ausreicht, mit realloc erweitert (nur Deppen benutzen Listen verkettet).



  • Hey hey ist ja gut 👎

    Ich kenn malloc() und realloc() noch net konnte dementsprechend mit deiner vorherigen Formulierung auch nix anfangen!!

    (nur Deppen benutzen Listen verkettet).

    Oder diejenigen, die es einfach nicht besser wissen, hm?
    Finde ich ist kein Grund beleidigend zu werden. 👍

    Werd mich jetzt in die Thematik reinlesen und es ausprobieren, tzdm dange :S


Anmelden zum Antworten