Vokabeltraining Programm in C

@BlackMark

Es geht nicht um die Aufgabenstellung - daran gibt es in der Tat wenig auszusetzen. Es geht darum, dass kein Mensch außerhalb des Elfenbeinturms der Akademien (in denen ich übrigens auch in forschender und lehrender Position sitze) auf die Idee kommen würde einen Vokabeltrainer in C zu programmieren. Erstens gibt es dafür wesentlich geeignetere Sprachen, zweitens sollte man C für das nutzen, wofür es am besten geeignet ist: Hardwarenahes Programmieren und Computing.
 
  • Gefällt mir
Reaktionen: wayne_757
Die Anzahl der Wörter ist ja erstmal nur die Anzahl der Leerzeichen + 1. Beim Schleifendurchlauf musst du dann nur noch sicherstellen, dass mehrfache Leerzeichen und solche am String-Anfang und -ende ignoriert werden.

Gruß Jens
Ergänzung ()

@KuestenNebel: Wenn in dem Kurs C gelernt werden soll, wäre eine andere Programmiersprache wohl kaum zielführend, und wenn offenbar Anfänger im Kurs sitzen, würde ich sie als Dozent auch keinen Treiber programmieren lassen …

Gruß Jens
 
  • Gefällt mir
Reaktionen: I'm unknown und new Account()
KuestenNebel schrieb:
Es geht darum, dass kein Mensch außerhalb des Elfenbeinturms der Akademien (in denen ich übrigens auch in forschender und lehrender Position sitze) auf die Idee kommen würde einen Vokabeltrainer in C zu programmieren.
Ist doch egal, wenn er dadurch C - die Programiersprache auch lernt.
 
@uburoi

Was genau versuchst du mit dieser falschen Dichotomie argumentativ zu erreichen? Ich sehe zwischen den beiden Polen "Vokabeltrainer" und "Treiber" ein Meer an Möglichkeiten, die näher an letzterem als an ersterem liegen. Um es kurz zu fassen: Man sollte den Leuten nicht unbedingt beibringen einen Schraubendreher als Hammer zu benutzen. Wenn es mal passiert, okay, aber im Schraubendreherkurs sollte man sich auf die Fähigkeiten des namensgebenden Werkzeugs konzentrieren. Aber wir sind hier ziemlich off-topic ...
 
KuestenNebel schrieb:
@uburoiWas genau versuchst du mit dieser falschen Dichotomie argumentativ zu erreichen? Ich sehe zwischen den beiden Polen "Vokabeltrainer" und "Treiber" ein Meer an Möglichkeiten, die näher an letzterem als an ersterem liegen.
Meine Alternative war nicht falsch, sondern nur überspitzt – zum Zweck der Veranschaulichung, der offenbar nicht erreicht wurde. Anders gewendet: Die Übung verfolgt offenbar im fest umrissenen Rahmen einer Veranstaltung, die wir nicht kennen, ein bestimmtes didaktisches Ziel, und unter diesem Gesichtspunkt scheint sie durchaus sinnvoll konzipiert zu sein.
Aber du hast recht – das führt vom Thema weg und spielt für den TO, der die Aufgabe so oder so lösen muss, ohnehin keine Rolle …

Gruß Jens
 
Hab bisher das geschrieben, aber ich komm einfach nicht klar darauf, dass er mir einen Schleifendurchgang am Ende zu viel macht. Ich bekomm dann immer return 3 bei der Fkt make_str. Die printfs sind zum ignorieren da, waren nur für mich um herauszufinden wo es hakt und das tuts so wies ausschaut bei der while schleife in der fkt read_file -> while(!feof(ptr)). Ich denke, dass er mir zum Schluss noch einmal in mein Schleifenkonstrukt reinspringt und ich so zum Schluss immer die falsche Anzahl der Worte bekomme obwohl zuvor schon die richtige Anzahl berechnet wurde. Solange ich hier nicht weiterkomme, macht weiterschreiben eigentlich nur wenig Sinn, bin am Verzweifeln, weil die Abgabe um Mitternacht ist (4 Tage für diese HÜ sind einfach zu wenig wenn man insgesamt jede Woche 6 HÜs in anderen Fächern bekommt und man neben Studium auch noch arbeiten gehen muss) :(


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




typedef struct
  {
      char *vocab_1;
    char *vocab_2;
  } vocabs;

char cntelements(char* element_str)
{
  int elements;

  for(elements = 0; element_str[elements] != '\n'; ++elements)
  {
    continue;
  }
  printf("elements: %d\n",elements);
  printf("elementstring: %s\n",element_str);

  return elements;
}

int counter(char *test_str)
{
  int i;
  int elements = cntelements(test_str);
  int cntWords = 0;

  printf("%s",test_str);
  for(i = 0; i < elements; i++)
  {
    if(((test_str[i+1] == ' ') || (test_str[i+1] == '\n')) && (test_str[i] != ' '))  
    {
      cntWords++;
      printf("cntstr: %c\n",test_str[i]);
      printf("cntWords: %d\n",cntWords);
    }
  }

  return cntWords;
}



int make_str(char *buffer_str)
{
  vocabs vocabs;
  const char *delimiter = " ";
  char *word_str;
  int i;
  char *tmp;

  int cntWords = counter(buffer_str);
  word_str = strtok(buffer_str, delimiter);


  while(word_str != NULL)
    {
      if(cntWords == 1)
      {
        vocabs.vocab_1 = word_str;
        printf("while: %s\n",word_str);
      }

      if(cntWords == 2)
      {
        vocabs.vocab_2 = word_str;
        printf("while: %s\n",word_str);
      }

      word_str = strtok(NULL, delimiter);    
     }

   
    if(cntWords != 2)
    {
      return 3;
    }

  return 0;

}


int read_file(char *filename)
{
  char buffer_str[255];
  int new_strs;


  FILE *ptr;
  ptr = fopen(filename, "r");

  if(ptr == NULL)
  {
    return 2;                                             //kann nicht geöffnet werden
  }
  while(!feof(ptr))
  {
    fgets(buffer_str, 255, ptr);
   
    new_strs = make_str(buffer_str);
   

    if(new_strs == 3)
    {
      return 3;                                           //falsche Formatierung einer Zeile im Dokument
    }
  }
  return 0;
}


int main(int argc, char *argv[])
{

  vocabs vocabs;
  int file_data;
  char *argx = argv[1];

  if(argc < 2)
  {
    printf("usage: [executable] filename\n");
    return 1;
  }

  file_data = read_file(argx);

  if(file_data == 2)
  {
    printf("ERROR: cannot open file %s\n", argx);
  }

  if(file_data == 3)
  {
    printf("ERROR: file %s invalid\n", argx);
  }

  printf("%d",file_data);
}
 
Habs jetzt mal so gemacht: Jetzt kommt die nächste Hürde, das struct Array :D


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




typedef struct
  {
      char *vocab_1;
    char *vocab_2;
  } vocabs;

char cntelements(char* element_str)
{
  int elements;
 
  for(elements = 0; element_str[elements] != '\n'; ++elements)
  {
    continue;
  }
  printf("elements: %d\n",elements);
  printf("elementstring: %s\n",element_str);
 
  return elements;
}

int counter(char *test_str)
{
  int i;
  int elements = cntelements(test_str);
  int cntWords = 0;
 
 
  printf("%s",test_str);
  for(i = 0; i < elements; i++)
  {
    if(((test_str[i+1] == ' ') || (test_str[i+1] == '\n')) && (test_str[i] != ' '))   
    {
      cntWords++;
      printf("cntstr: %c\n",test_str[i]);
      printf("cntWords: %d\n",cntWords);
    }

    if(test_str[i] == '\0')
        return -1;
  }
  
  return cntWords;
}



int make_str(char *buffer_str)
{
  vocabs vocabs;
  const char *delimiter = " ";
  char *word_str;
  int i;
  char *tmp;
 
  int cntWords = counter(buffer_str);

  word_str = strtok(buffer_str, delimiter);
 
 
  while(word_str != NULL)
    {
      
      if(cntWords == 1)
      {
        vocabs.vocab_1 = word_str;
        printf("while: %s\n",word_str);
      }

      if(cntWords == 2)
      {
        vocabs.vocab_2 = word_str;
        printf("while: %s\n",word_str);
      }

      word_str = strtok(NULL, delimiter);
        
    }
    
    if(cntWords != 2 && cntWords != -1)
    {
      return 3;
    }
    
  return 0;
 
}


int read_file(char *filename)
{
  char buffer_str[255];
  int new_strs;
 

  FILE *ptr;
  ptr = fopen(filename, "r");

  if(ptr == NULL)
  {
    return 2;                                             //kann nicht geöffnet werden
  }
  while(!feof(ptr))
  {
    fgets(buffer_str, 255, ptr);
    
    new_strs = make_str(buffer_str);
    

    if(new_strs == 3)
    {
      return 3;                                           //falsche Formatierung einer Zeile im Dokument
    }
  }
  return 0;
}


int main(int argc, char *argv[])
{

  vocabs vocabs;
  int file_data;
  char *argx = argv[1];

  if(argc < 2)
  {
    printf("usage: [executable] filename\n");
    return 1;
  }
 
  file_data = read_file(argx);

  if(file_data == 2)
  {
    printf("ERROR: cannot open file %s\n", argx);
  } 

  if(file_data == 3)
  {
    printf("ERROR: file %s invalid\n", argx);
  }
 
  printf("%d",file_data);
}
 
So jetzt hab ich ein Problem bei realloc:
Immer wenn realloc aufgerufen wird, bekomme ich invalid next size:


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




typedef struct
  {
      char *vocab_1;
    char *vocab_2;
  } vocabs;

int struct_array(char *word_1, int lines, int cntWords)
{
  static int x = 15;
  static int y = 0;
  printf("%d\n",lines);
  vocabs *arr_vocab = malloc(10*sizeof(char));

  if(arr_vocab == NULL)
  {                                       //out of memory
    return 4;
  }

  if(lines > (9 + y))
  {
    y += 5;
    x += 5;
    
    arr_vocab = realloc(arr_vocab, x*sizeof(char));

    if(arr_vocab == NULL)
    {
      return 4;
    }
  }

  if(cntWords == 1)
  {
    arr_vocab[lines].vocab_1 = word_1;
  }

  if(cntWords == 2)
  {
    arr_vocab[lines].vocab_2 = word_1;
  }
 
 
return 0;
}

char cntelements(char* element_str)
{
  int elements;
 
  for(elements = 0; element_str[elements] != '\n'; ++elements)
  {
    continue;
  }

 
  return elements;
}

int counter(char *test_str)
{
  int i;
  int elements = cntelements(test_str);
  int cntWords = 0;
 
 

  for(i = 0; i < elements; i++)
  {
    if(((test_str[i+1] == ' ') || (test_str[i+1] == '\n')) && (test_str[i] != ' '))   
    {
      cntWords++;
      
    }

    if(test_str[i] == '\0')
        return -1;
  }
  
  return cntWords;
}



int make_str(char *buffer_str, int lines)
{
  vocabs vocabs;
  const char *delimiter = " ";
  char *word_str;
  int i;
  char *tmp;
  int X;
 
  int cntWords = counter(buffer_str);

  word_str = strtok(buffer_str, delimiter);
 
 
  while(word_str != NULL)
    {
      
      if(cntWords == 1)
      {
        X = struct_array(word_str, lines, cntWords);
      
      }

      if(cntWords == 2)
      {
        X = struct_array(word_str, lines, cntWords);
      
      }

      word_str = strtok(NULL, delimiter);
        
    }
    
    if(cntWords != 2 && cntWords != -1)
    {
      return 3;
    }
    
  return 0;
 
}


int read_file(char *filename)
{
  char buffer_str[255];
  int new_strs;
  int cnt_lines = 0;
 

  FILE *ptr;
  ptr = fopen(filename, "r");

  if(ptr == NULL)
  {
    return 2;                                             //kann nicht geöffnet werden
  }
  while(!feof(ptr))
  {
    cnt_lines++;
    fgets(buffer_str, 255, ptr);
    
    new_strs = make_str(buffer_str,cnt_lines);
    

    if(new_strs == 3)
    {
      return 3;                                           //falsche Formatierung einer Zeile im Dokument
    }
  }
  return 0;
}







int main(int argc, char *argv[])
{

  vocabs vocabs;
  int file_data;
  char *argx = argv[1];
 

  if(argc < 2)
  {
    printf("usage: [executable] filename\n");
    return 1;
  }
 
  file_data = read_file(argx);

  if(file_data == 2)
  {
    printf("ERROR: cannot open file %s\n", argx);
  } 

  if(file_data == 3)
  {
    printf("ERROR: file %s invalid\n", argx);
  }
 
  printf("%d",file_data);
}
 
Deine main sieht niemals irgendwelche eingelesenen Daten. Du solltest die Datenstruktur dort anlegen.
Darüber hinaus allokierst du ständig Speicher in struct_array, verwendest diese Pointer aber nirgends weiter. Da du den Speicher nachher nicht freest, hast du hier ein Speicherleck.
Schau dir im Debugger an, was an welcher Adresse im Speicher liegt.
Und verwende, wie in der Aufgabenstellung bereits gefordert, ertens ein Array vom Typ *vocabs, das ausschließlich die Adressen der Speicherbereiche enthält. Und zweitens speichere jeden String irgendwo im Heap ab, das muss dann auch nicht zwingend ein zusammenhängender Speicherbereich für alle Strings sein. (d.h. hierfür brauchst du kein realloc.)
 
Laut Spezifikation würde nworte = sscanf(buffer_str, "%s %s", w1, w2) reichen (imho). Ansonsten ist das eine schöne Aufgabe, welche aber leider gleich mehrere schwierige Probleme (für Anfänger) beinhaltet.
 
Zurück
Oben