Vokabeltraining Programm in C

K

kleine_susi

Gast
Hallo, ich weiß echt nicht wie ich sowas umsetzen soll:
  • Schreiben Sie ein Programm, welches Vokabelpaare (ein Wort und dessen Übersetzung in eine andere Sprache) aus einer Datei liest. Im Anschluss wird dem Benutzer jeweils ein Element eines Paares ausgegeben und die richtige Übersetzung muss durch den Benutzer eingegeben werden. Zum Abschluss wird dem Benutzer angezeigt wie viele richtige Antworten gegeben wurden.
  • Definieren Sie einen Datentyp für die Vokabelpaare. Die entsprechende Struktur soll zwei C-Strings (als Character-Pointer) als Elemente beinhalten.
  • Die Vokabelpaare werden in einer Textdatei gespeichert, wobei jeweils pro Zeile ein Vokabelpaar gespeichert wird. Die beiden Elemente des Vokabelpaares werden durch mindestens ein Leerzeichen getrennt. Einzelne Zeilen sind mit einem Zeilenumbruch (\n) abgeschlossen. Es dürfen zu Zeilenbeginn und Zeilenende beliebig viele Leerzeichen vorliegen. Sollte eine Zeile nicht genau zwei Elemente enthalten ist die Vokabeldatei ungültig (siehe Fehlermeldungen).
Programmablauf:
Das Programm wird mit einem Kommandozeilenparameter aufgerufen. Dieser gibt den Dateinamen der zu öffnenden Vokabeldatei an. Sollte das Programm ohne Kommandozeilenparameter aufgerufen werden kommt es zu einer Fehlermeldung. Sollte das Programm mit mehr als einem Kommandozeilenparameter aufgerufen werden, so werden alle Parameter nach dem ersten ignoriert.
Im ersten Schritt liest das Programm die Vokabeldatei ein. Die Inhalte der Datei müssen hierbei am Heap gespeichert werden (siehe Spezifikation).
Im zweiten Schritt wird das erste Element des ersten Vokabelpaares gefolgt von der Zeichenfolge " - " ausgegeben und auf eine Benutzereingabe gewartet.
Die vom Benutzer eingegebene Zeichenkette wird mit dem zweiten Element des Vokabelpaares verglichen. Stimmen die beiden Zeichenketten überein wird "correct\n" ausgegeben, ansonsten "incorrect\n".
Anschließend wird mit dem nächsten Vokabelpaar fortgesetzt, wobei in diesem Fall das zweite Element ausgegeben wird und die Eingabe mit dem ersten Element verglichen wird.
Für jedes gerade Vokabelpaar (0., 2., 4., ...) wird das erste Element des Paares ausgegeben und die Eingabe mit dem zweiten Element verglichen. Für jedes ungerade Vokabelpaar (1., 3., 5., ...) wird das zweite Element des Paares ausgegeben und die Eingabe mit dem ersten verglichen.
Abschließend wird eine Statistik ausgegeben: "[correct] / [pairs]\n" wobei [correct] durch die anzahl der richtig beantworteten Vokabeln und [pairs] durch die Anzahl der Vokabelpaare ersetzt wird.

Dateiinhalt muss am Heap gespeichert werden
  • Vokabelpaare werden in der definierten Datenstruktur am Heap gespeichert
  • Pointer auf die Datenstrukturen werden in einem dynamisch wachsenden Array gespeichert
  • Das Array soll anfangs 10 Elemente groß sein. Wann immer notwendig soll es um 10 Elemente vergrößert werden. (10->20->30->...)


Ich hab jetzt schon stundenlang herumprobiert. Aber ich hab zwei große Probleme. Wie benutze ich in diesem Fall realloc()? Und wie kann ich auf Wörter in einer Zeile überprüfen? Hätte es mit einer while Schleife versucht der den FILE Pointer überprüft, aber das darf man lt Warnings nicht machen. Weiß echt nicht mehr weiter, sitze seit halb 7 (am Morgen sei gesagt) an diesem Beispiel und hab effektiv noch nichts geschafft :/
 

wayne_757

Lt. Junior Grade
Dabei seit
Aug. 2004
Beiträge
423
Also in der Aufgabenstellung ist eigentlich alles haarklein erklärt.

Aber anhand deiner Fragestellung fehlen dir die absoluten Basics.

Am besten also nochmal das Script zur Vorlesung durcharbeiten und vor allem verstehen.
 

KuestenNebel

Lieutenant
Dabei seit
Aug. 2019
Beiträge
892
Mich beeindruckt immer wieder für welchen abstrusen Unsinn die Sprache C missbraucht wird ... sorry, aber dein Dozent stellt ziemlich schlechte Übungsaufgaben.
 

KuestenNebel

Lieutenant
Dabei seit
Aug. 2019
Beiträge
892
Du bringst es auf den Punkt: Wir sind hier keine Hausaufgabenhilfe, aber konkrete Fragen sind natürlich willkommen.
 
K

kleine_susi

Gast
Ich möcht ja nur wissen wie man hier eine Zeile auf die Anzahl der Wörter überprüfen kann und wie man das mit realloc umsetzt, damit erst dann der string erweitert wird sobald kein platz mehr im string ist. Die Hausaufgabe will ich eh selber lösen aber ich check halt genau diese zwei punkte nicht. Ihr müsst mir auch keinen Code schreiben, nur erklären wie sowas geht :)
 

new Account()

Rear Admiral
Dabei seit
Mai 2018
Beiträge
5.729

new Account()

Rear Admiral
Dabei seit
Mai 2018
Beiträge
5.729
K

kleine_susi

Gast
Ja ich weiß was realloc ist und wie es funktioniert. Wie gesagt das Problem ist, dass ich nicht weiß wie man da eine Abfrage einbaut, dass das Array erst erweitert wird wenn der Platz im Array zu knapp wird (also wie müsste die if Bedingung da aussehen??)
 

new Account()

Rear Admiral
Dabei seit
Mai 2018
Beiträge
5.729
da steht, doch, dass es am Anfang 10 Elemente groß ist (Kapazität).
und wenn du neue Elemente einfügst, und du 10 Elemente eingefügt hast und nun ein 11. Element einfügen willst, machst es größer.

if(aktuelleGröße==Kapazität){ mache array größer }
 
K

kleine_susi

Gast
Ok hab jetzt schon ein bisschen mehr Plan, aber ich bekomm durch folgende Zeilen immer einen Speicherzugrifferror:

FILE *fp;
fopen(filename, "r");
fgets(buffer_str, 255, fp);

filename ist der parameter der funktion, also zb. file.txt
Ergänzung ()

Ok hat sich gerade erledigt:
FILE *ptr;
ptr = fopen(filename, "r");
fgets(buffer_str, 255, ptr);

Anscheinend ist C halbwegs streng was Form angeht....
 
Zuletzt von einem Moderator bearbeitet:

new Account()

Rear Admiral
Dabei seit
Mai 2018
Beiträge
5.729
K

kleine_susi

Gast
Achso das ist gleich eine eigene Adresse, dachte dass heißt nur, dass es ein pointer ist und FILE definiert die Adresse
 
K

kleine_susi

Gast
So jetzt hab ichs mal soweit, dass er mir nur das erste Wort ausließt, allerdings verliere ich dadurch immer den letzten Buchstaben. Hat irgendwer ne bessere Idee ohne, dass ich jetzt eine weitere if Bedingung brauche?



C:
     while(buffer_str[i+1] != 32 || buffer_str[i] == 32)          //While Schleife bis erstes Leerzeichen nach ersten Wort
    {
     
      if(((buffer_str[i] > 64 && buffer_str[i] < 91) ||
        (buffer_str[i] > 96 && buffer_str[i] < 123)) && (buffer_str[i] != 32))    //erstes Wort in neuen String einlesen
      {
        buffer[j] = buffer_str[i];
        j++;                                    
        countWords++;
             
      }

      i++;
     
    }
Ergänzung ()

So würds funktionieren, aber ist halt dann schon wieder um 4 Zeilen länger

Code:
 while(buffer_str[i+1] != 32 || buffer_str[i] == 32)         
  {
        
    if(((buffer_str[i] > 64 && buffer_str[i] < 91) ||
      (buffer_str[i] > 96 && buffer_str[i] < 123)) && (buffer_str[i] != 32))   
    {
      buffer[j] = buffer_str[i];
      j++;                                     
      countWords++;               
    }

    i++;

    if(buffer_str[i+1] == 32 && buffer_str[i] != 32)
    {
      buffer[j] = buffer_str[i];       
    }
  }
 
Zuletzt von einem Moderator bearbeitet:

BlackMark

Lt. Commander
Dabei seit
Juni 2007
Beiträge
1.319
Mich beeindruckt immer wieder für welchen abstrusen Unsinn die Sprache C missbraucht wird ... sorry, aber dein Dozent stellt ziemlich schlechte Übungsaufgaben.
Was? Von all den Übungsaufgaben die über die Jahre hier im Forum gepostet wurden ist das sicherlich eine der besten. Die Aufgabenstellung ist sehr ausführlich erklärt und gibt den kompletten Lösungsweg vor, was für eine Anfängeraufgabe sehr hilfreich ist. Die Konzepte die verlangt werden sind nützlich und sinnvoll (custom data-types, file I/O, error handling, dynamic memory). Und ein Vokabeltrainer ist ein nützliches Programm und nichts künstlich konstruiertes ohne wirklichen Verwendungszweck. Außerdem, wie wird hier C missbraucht?

@kleine_susi Deine while-Schleife ist komplett unlesbar. Soll ich auswendig wissen was 32, 64, 91, 96, und 123 für ASCII characters sind? Du kannst auch einfach buffer_str[i] == ' ' schreiben, dann weiß man zumindest was für characters gemeint sind.

Abgesehen davon macht man das nicht von Hand, wenn es Funktionen in der standard library gibt, die genau das schon machen. Schau dir strtok an, damit kannst du einen string in tokens (einzelne Wörter, in deinem Fall) zerlegen. strtok ignoriert dann auch mehrfach vorkommende Leerzeichen. Siehe hier.

Gruß
BlackMark
 

uburoi

Lieutenant
Dabei seit
Aug. 2008
Beiträge
817
Da ich neulich auch mal angefangen habe, mich mit C zu beschäftigen (reines Hobby ohne Profi-Ansprüche) und mir eine ähnliche Aufgabe gestellt hatte, möchte ich noch auf ein Problem deiner while-Schleife hinweisen: Du fragst dort nur Buchstaben von A bis Z bzw. a bis z ab. Wenn du aber mal auf der Konsole printf(“über“) ausgibst, wirst du feststellen, dass “ü“ nicht mit einem, sondern mit zwei Bytes kodiert wird, da es kein Ascii-Zeichen ist. Für einen Vokabeleintrag wie “similar ähnlich“ wird deine Schleife also nicht funktionieren, gar nicht zu reden etwa von einem Altgriechisch-Vokabelverzeichnis. (Ein Problem, das englischsprachige Tutorials in der Regel auch leider übergehen, da sie das Problem mit Umlauten nicht kennen …)
Das Problem lässt sich aber leicht lösen, wenn man sich anhand einiger Beispielausgaben mal ansieht, wie C mit Nicht-Ascii-Zeichen umgeht. ;)

Gruß Jens
 
K

kleine_susi

Gast
So habe es jetzt mit strtok versucht. Aber leider werden hierbei Leerzeichen nicht ignoriert :( Jemand eine Idee?

Edit: Funktioniert doch! :) Aber muss mir noch überlegen wie ich dann die Wörter zähle
 
Zuletzt von einem Moderator bearbeitet:
Top