# Vokabeltrainer C++



## scrubs2k5 (30. Juni 2006)

Hallo alle beisammen!
Vielleicht kann mir ja jemand von euch helfen:
Ich möchte einen Vokabeltrainer programmieren, der folgendes können soll:


_Bei jedem Start des PCs werden 10 Vokabeln zufällig abgefragt._
_Vokabeln zufällig abgefragt. Dazu soll eine Karteikartenmethode _
_(drei Kästen! - Vokabeln die bekannt sind, wandern von 1 -> 2 _
_- und alls die in 2 sind wandern von 2 -> 3 bzw. "raus")_
_programmiert werden._
_- Die zu lernenden VOlabeln stehen in einer Datei, die mit "Bordmitteln" (Editor, Word, Excel etc.) zu bearbeiten ist._

Ich habe auch schon einen Ansatz, leider komme ich nicht weiter. Ich kann zwar Vokabeln einlesen, aber immer nur 1 Deutsches und 1 Englisches Wort. Kann also nicht alle in einem Array speichern. 2tes Problem ist, dass ich nur Wörter ohne Leerzeichen nehmen kann, da er das Leerzeichen als Trennzeichen benutzt, und dann weiterspringt. Bitte nicht so schwierige Sachen benutzen, da ich noch Anfänger bin.

Hier der Code von mir:

```
#include <stdio.h>
#include <conio.h>
void dateioeffnen(void); //Funktion zum öffenen der Datei
int eingabe(void);      //Funktion zum öffnen der Abfragen der Eingabe
void menue(void);        //Funktion zum darstellen des Menüs
int main(void)
{
   int i;
   do{
    i = eingabe();
    getch();
   }while(i); //Solange i=1 ist
 return 0;
}
void dateioeffnen(void)
{
 FILE *pf = fopen("Vok-DE-EN.txt", "r"); //Deklaration
   FILE *pf2 = fopen("Zwischen.txt", "w");
 char in1[20], in2[20];
 if(!pf) {
  printf("Konnte die Datei nicht oeffnen\n");
 }
 while(!feof(pf)) { //Solange das Dateiende nicht erreicht ist
  if(fscanf(pf, "%s %s\n", in1, in2) == EOF) { //Einlesen wenn Dateiende noch nicht erreicht ist
   break;
  } else {
   printf("%s %s\n", in1, in2); //Testweise Ausgabe
         fprintf(pf2, "%s %s\n", in1, in2); //Daten in neue Datei schreiben
  }
 }
 fclose(pf);
}
int eingabe(void) //Eingabeabfrage
{
   clrscr(); //Bildschirm löschen
   int wahl;
   menue(); //Menüdarstellung aufrufen
   do{
    scanf("%i", &wahl); //Auswahl abfragen
      if(wahl<0||wahl>3) //Bei falscher Eingabe wiederholen
      {
       printf("Falsche Eingabe!");
         getch();
         clrscr();
         menue(); //Funktion Menü neu aufrufen
      }
   }while(wahl<0||wahl>3);
   switch(wahl)
   {
    case 0: printf("Programm beendet"); return 0; break;
      case 1: printf("Auswahl 1"); return 1; break;
      case 2: printf("Auswahl 2"); return 1; break;
      case 3: dateioeffnen(); return 1; break;
   }
}
void menue(void) //Menüdarstellung
{
  printf("Vokabeltrainer\n\n");
   printf("1. Lernen\n");
   printf("2. Hinzufuegen\n");
   printf("3. Zufaellige Abfrage\n\n");
   printf("0. Ende\n\n");
   printf("Bitte treffen sie ihre Auswahl: ");
}
```

Achja: Die Datei Vok-DE-EN.txt hat den Aufbau:
DeutschesWort EnglischesWort
Also:
gehen go
schlafen sleep
hören hear


----------



## Ritchie_Fomm (4. Juli 2006)

Hallo, 

Ich würde nicht über die <stdio> gehen sondern über die <fstream>
stdio mit FILEHandler ist noch ein C-Relikt. Um das schön sauber mit Lerrzeichen und Zeilen einlesen solltest du wie gesagt mit LIB fstream arbeiten. Der Funktionsumfang ist m.E. nach besser vor allen Dingen was Insert Functions usw und rauslesen nach bestimmten Zeichen angeht.

Hier ein kleines Beispiel:

	m_ifStream.open(m_lpszFilePath, ios::in);

	if(m_ifStream)
        {

             // Größe des Files 
	     m_ifStream.seekg(-1, ios::end);
 	     m_lStreamLength = m_ifStream.tellg();
             //und zurück auf Anfang
            m_ifStream.seekg(0,ios::beg);
            while(m_lStreamLength > lPos)
		{
                       // lpszLine musst du noch deklarieren
			m_ifStream.getline(lpszLine, m_lStreamLength);
                        lPos = m_ifStream.tellg();
                }
         }

Desweiteren würde ich wenn du das als Textfile baust in Blöcken bauen! ZB:

DS
gehen
go

DS
sehen
see

dadurch bleibst du flexibler was die Daten angeht sowie die Navigation inklusive das auslesen der Daten.

Wenn du beim Filhandler bleiben willst würde ich statt mit fscanf mit fread arbeiten ohne irgendwelche returns arbeiten und Datasetheader bauen, wäre auf jden Fall eine saubere Lösung wenn du mit dem Handler arbeiten möchtest.

Grüße
R.


----------



## scrubs2k5 (5. Juli 2006)

Danke für die Antwort!
Habe aber ein paar fragen:
Da ich noch nie mit LIBs gearbeitet habe, habe ich überhaupt keine Ahnung wie das funktioniert. Und zu fread, was sind Datasetheader?

mfg


----------



## Ritchie_Fomm (5. Juli 2006)

Hallo, 

hier wird es wohl reichen wenn du fStream includierst also mit
#include <fstream>

Mit einem DatasetHEader ist in diesem Fall ganz einfach gemeint, das du bei jedem Satz Deutsch<->Eglisch Vokabel noch mitgibst wieviel Speicherplatz die beiden zum Beispiel verbrauchen usw.. Dies hat jedoch nichts spezifisch mit fread zu tun sondern ist eine gängige Methode um auf Daten welche in Dateien abgelegt sind zuzugreifen bzw. zu navigieren.

Hattest du schon einmal darüber nachgedacht die Vokabeln auch anders abzulegen? 

Grüße
R.


----------



## scrubs2k5 (5. Juli 2006)

Achso,

werd mir das mit dem fstream mal ansehen. Wenn du eine Idee hast, wie man die Daten besser ablegen kann, immer her mit den Ideen

Danke!


----------



## Ritchie_Fomm (5. Juli 2006)

Ich denke da an eine kleine DB entweder MSAccess bzw. SQLExpress(wobei nur mit .NetStudio Express zum entwickeln).

Ist bei größeren Datenmengen auf jeden Fall auch schneller.

Grüße
R.


----------



## scrubs2k5 (5. Juli 2006)

Ich denke eine Datenbank wäre ein gute Idee, allerdings soll die Datei mit den Vokabeln leicht editierbar, bzw. auf jedem Computer editierbar sein, damit jeder seine eigenen Vokabeln ganz leicht einfügen kann.

mfg


----------



## Ritchie_Fomm (5. Juli 2006)

wenn das ganze nur auf einem Windowssystem laufen soll, benutze doch einfach eine AccessDB, den Treiber hat jeder durch Windows und du lieferst die *.mdb mit editieren kann man das ganze dann entweder übder einen Dialog in deinem Programm.



Grüße
R.


----------



## scrubs2k5 (5. Juli 2006)

Okay, das hört sich vernünftig an, jedoch habe ich keine Ahnung, wie man in eine Datenbank schreibt.
Und zu dem fstream, könntest du da mal ein Beispiel posten, evntuell mit bezug auf das Vokablprogramm?

Vielen Dank!


----------



## Ritchie_Fomm (5. Juli 2006)

einlesen der Daten


```
// würde ich jedoch als KLasse bauen
//desweiteren charPointer verwenden ist jedoch hier in dem Beispiel
//erstam nicht nötig

typedef struct VokSet
{
    char lpszGerman[50];
    char lpszEnglish[50];
};

void ReadFile(...)
{
        ifstream _ifStream;
	char lpszStreamLine[150];
        VokSet _VokSet[3]; // wie groß das Teil sein soll kannst du ja vorher in dem Filheaderbeschreiben
        long lCounter = -1;

	_ifStream.open(lpszFile, ios::in);

	if(!_ifStream)
		return -1;

	_ifStream.seekg(0, ios::beg);

	while(!_ifStream.eof())
	{
               lCounter++;
		_ifStream.getline(lpszStreamLine,lFileLength);
                strcpy(_VokSet[lCounter].lpszeGerman, lpszStreamLine);
                ............ usw usw.

        }
}

// und noch schnell reinschreiben
void WriteFile(const char *lspzFileContent)
{
 //  ... wenn ich schreibe baue ic meistens das File vorher zusamm
 // uns schreibe das ganze mit einem Filehandler
}
```


----------



## scrubs2k5 (5. Juli 2006)

Viel Dank!
Ich schaue mir das nachher mal in Ruhe an, da ich im Moment an der Arbeit bin. Aber wirklich vielen Dank für deine Bemühungen!

mfg


----------



## Terrakotta001 (2. Juli 2008)

Hallo,
auch hier wieder große zufall. Möchte auch ein Vokabeltrainer programmiern.

Habe ganz kurz auf dein code eingeschaut und sah, dass du mit array arbeitest.
Hier ist man an dem array grösse gebunden. naja, es ist eine frage der Nutzung. Mein Vokabeltrainer soll die leistung deines ähnlich sein.

ich habe mit STL gearbeitet. 
1) wird der text eingelesen. Mit ' : ' doppelpunkt soll deutsches wort von englishen trennen.
2) mit getline und istringstream lässt die trennung leicht bewerkstelligen
3) mit der trennung wird dann auch gleich in die liste eingefügt (ähnlich wie array nur ohne Arraygröße + einiges an Vorteil Funktionen unwiderstehlich)
4) ja wenn die liste schon mal aufgefüllt ist, dann steht dir alles zur verfügung was dir dein herz begehrt.

Struktur sieht bei mir so.
Klasse: Vokabel => Eigenschaften sind string deutsch und english
dann die main mit list<Vokabel> lstVokabel. über pushback lässt sich alle vokabel sehr leicht einfügen. ja und wie gesagt dann steht dir alles offen.

einziges manko bei mir, ist die for_each. ich kann mir kein Vokabel elemente ausgeben. Ich weiss aber dass man mit operator übergabe arbeiten muss. weiss aber nicht wie. Einlesen und einfügen ins liste ist bei mir klaro.

vielleicht kann man mir hier weiterhelfen.

hier unten ist nochmal der code. ist ziemlich lang ... aber ohne inhalt. Die Zeile mit dem for_each ist mein problem, denn so geht aufjedenfall nicht.


===================

#include <iostream>
#include <string>
#include <fstream>
#include <list>
#include<algorithm>
#include<vector>

#include "Vokabel.h"
#include "Ausgabe.h"

using namespace std;

void main()
{
list<Vokabel> lstVokabel;
list<Vokabel> lstVokabelFalse;
list<Vokabel> lstVokabelCorrect;

list<Vokabel>::iterator iter;

iter = lstVokabel.begin();
// Vokabel aus Text Datei ins Vokabel Liste Einfügen
lstVokabel.push_back(Vokabel("one", "ein"));
lstVokabel.push_back(Vokabel("two", "zwei"));
lstVokabel.push_back(Vokabel("three", "drei"));
lstVokabel.push_back(Vokabel("four", "vier"));

//Abfragen solange lstVokabel leer ist

for_each(lstVokabel.begin(), lstVokabel.end(), iter->Foreach_Show); ////////FEHLER//


}

============================================================
=============================================================

#pragma once
#include <string>
using namespace std;
class Vokabel
{
private:
string _deutsch;
string _english;

public:
Vokabel(void);
~Vokabel(void);
Vokabel(string, string);

void Show();
void Foreach_Show(string, string);
string Get_deutsch();
void Set_deutsch(string);
string Get_english();
void Set_english(string);
};
===========================================================
====================================================
#include "Vokabel.h"
#include <string>
#include <iostream>
using namespace std;

Vokabel::Vokabel(void)
{
}
Vokabel::Vokabel(string de, string en)
{
_deutsch = de;
_english = en;
}

Vokabel::~Vokabel(void)
{
}

void Vokabel::Show()
{
cout<< _deutsch << " " << _english<<endl;
}
void Vokabel::Foreach_Show(string de, string en)
{
cout<< de << " " << en <<endl;
}

string Vokabel::Get_deutsch()
{
return _deutsch;
}
void Vokabel::Set_deutsch(string de)
{
_deutsch = de;
}

string Vokabel::Get_english()
{
return _english;
}
void Vokabel::Set_english(string en)
{
_english = en;
}


----------

