[C++] Arrays

ChristianK

Well-known member
ID: 85965
L
25 Mai 2006
92
1
Hi,

sitze nun schon lange an diesem Problem. Im Internet habe ich noch nicht so recht viel gelesen, was mir helfen könnte.

Ich will eine Funktion haben, der ich mitgeben kann, wie groß die Eingabe maximal sein darf. Dies habe ich so gemacht:

Code:
char checkl(int l) {
	char tmp[200];

   while (1) {
   	gets(tmp);
   	if (strlen(tmp) > l) {
      	cout << "\n\tFehlerhafte Eingabe! Die Laenge darf " << l << "nicht ueberschreiten!\n\n\t";
      } else {
      	return tmp;
      }
   }
}

Code:
cout << "\tVorname: \t\t";
Pers.vorname = checkl(30);

Jedoch klappt dieser Code nicht. Was mache ich falsch? Gebe ich das Char-Array falsch zurück?

Pers.vorname ist ein struct mit einer Laenge von 30.


Hoffe ihr könnt mir helfen,
Christian
 
Lass mich raten: Es steht nur Müll in Pers.vorname ? ;)

So wie ich das sehe, willst du eine lokale Variable, der beim Prozedurende ungültig wird, weiterverwenden. Außerdem gibst du nur Typ char zurück.

Probiers mal so:
PHP:
char* checkl(int l) {
   char* tmp=new char[200];

   while (1) {
       gets(tmp);
       if (strlen(tmp) > l) {
          cout << "\n\tFehlerhafte Eingabe! Die Laenge darf " << l << "nicht ueberschreiten!\n\n\t";
      } else {
          return tmp;
      }
   }
}

//....

struct {
  char* vorname;
} Pers;

Pers.vorname=checkl(30);

//....

delete Pers.vorname; // Aufräumen nicht vergessen !
edit:
Wenn dir jemand mehr als 200 Zeichen eintippt, kackt das Programm natürlich trotzdem ab ;)
 
Aber ich hoffe mal, dass keiner 200Zeichen eingeben wird ;)


EDIT:

Geht immer noch nicht. Glaube sogar gleicher Fehler:

Lvalue required

Der Compiler zeigt dann auf Pers.vorname. Jedoch habe ich nicht alles so geändert wie du es gesagt hast, sonst kommen 20 Fehler hinzu, so sieht es bei mir aus:

Code:
Telefonbuch Pers;

Code:
class TelefonBuch {
	char vorname[30];
   char nachname[30];

   char festanschluss[50];
   char fest_provider[30];

   char mobilanschluss[50];
   char mobil_provider[30];

   char email[60];

   char strasse[40];
   char hausnummer[5];
   char plz[8];
   char ort[50];

   char kategorie[30];

   public:	void input(void);
	   		void output(void);
            void export(int);
            void del(void);
            void sort(void);
            void change(void);
            void search(void);
   private: void del_all(void);
            void del_e(int);
};
 
Aber ich hoffe mal, dass keiner 200Zeichen eingeben wird ;)
Microsoft hofft auch auf vieles.... drum läuft Windows auch immer so stabil :LOL:

Zum Testen kannst du solche Programme ja schreiben, aber wenn das wirklich was werden soll, solltest du eher so vorgehen:
PHP:
// Pseudocode
char* buffer=new char[MAX_BUFFER_LEN]; // allocate buffer
int c=0; // position for next databyte
char key;
while(need_eingabe)
{
  if(!key_ready())
    continue;

  key=get_key();  
  if(key==27)
    need_eingabe=false; // esc terminates

  buffer[c++]=key;
  if(c==MAX_BUFFER_LEN-1)
    break; // buffer full
}
buffer[c]='\0'; // add null-terminate
 
Geht immer noch nicht. Glaube sogar gleicher Fehler:

Lvalue required

Der Compiler zeigt dann auf Pers.vorname. Jedoch habe ich nicht alles so geändert wie du es gesagt hast, sonst kommen 20 Fehler hinzu, so sieht es bei mir aus:
Du benutzt feste Datenfelder, ich dynamische.
Wenn du das unbedingt beibehalten willst, musst du das Ergebnis eben in das Feld reinkopieren:
PHP:
char* checkl(int l)
{
  // wie letzter Post von mir
}

struct Pers
{
  char vorname[30]; // fixed
}

char* vorname=checkl(30);
memcpy(Pers.vorname,vorname,30); // copy memory
delete vorname;
Kostet halt doppelt Speicher.

Alternativ kannst du checkl() gleich den Buffer mitübergeben, das wäre cleverer :think:
PHP:
void checkl(char* buffer,int l)
{
  // mit buffer arbeiten, statt mit neuem Array
}

checkl(Pers.vorname,30);
 
Ich versuche das mal ;)

Also das ganze einfach in ide Funktion einfügen, und hoffen das es geht ;) Kann es da sein, dass man was geschriebenes nicht mehr rückgängig machen kann, oder wie sieht das aus?
 
Du benutzt feste Datenfelder, ich dynamische.
Wenn du das unbedingt beibehalten willst, musst du das Ergebnis eben in das Feld reinkopieren:
PHP:
char* checkl(int l)
{
  // wie letzter Post von mir
}

struct Pers
{
  char vorname[30]; // fixed
}

char* vorname=checkl(30);
memcpy(Pers.vorname,vorname,30); // copy memory
delete vorname;
Kostet halt doppelt Speicher.

Alternativ kannst du checkl() gleich den Buffer mitübergeben, das wäre cleverer :think:
PHP:
void checkl(char* buffer,int l)
{
  // mit buffer arbeiten, statt mit neuem Array
}

checkl(Pers.vorname,30);



Es geht immer noch nicht, weil ich nicht weiß, wo ich da ein * hinsetzen soll ;)

Code:
void checkl(char* buffer,int l) {
   char* tmp=new char[200];

   while (1) {
       gets(tmp);
       if (strlen(tmp) > l) {
          cout << "\n\tFehlerhafte Eingabe! Die Laenge darf " << l << "nicht ueberschreiten!\n\n\t";
      } else {
          buffer = tmp;
          break;
      }
   }
}

Wenn ich *buffer = *tmp hinschreibe, bekomme ich schon mal ein Buchstabe in Pers.vorname. Möchte aber gerne alle :)
 
Zuletzt bearbeitet:
Wenn ich *buffer = *tmp hinschreibe, [...]
Wichtig in C++: Erst Hirn einschalten, dann erst wild mit Sternen werfen ;)
Du übergibst doch den Buffer, damit die Funktion weiß, wo sie reinschreiben soll. Wieso überschreibst du dir den Parameter also wieder, wenn du ihn eigentlich haben willst ?! Ergo is diese Zeile ober-sinnlos.

Nochmal ganz ausführlich, Zeile für Zeile:
PHP:
void checkl(char* buffer,int l) {
   while (1) {
       gets(buffer); // in den Buffer lesen (und btw. hoffen, dass der User ihn nicht sprengt)
       if (strlen(buffer) > l) {
          cout << "\n\tFehlerhafte Eingabe! Die Laenge darf " << l << "nicht ueberschreiten!\n\n\t";
      } else {
          return; // was noch aufhalten ?! Die Eingabe steht in buffer drin und erfüllt die kürzer-gleich l
      }
   }
}
Jetzt das ganze noch zusammenfassen, dass man es leichter lesen kann:
PHP:
void checkl(char* buffer, int l) {
    gets(buffer);

    while(strlen(buffer) > l) {
        cout << "\n\tFehlerhafte Eingabe! Die Laenge darf " << l << "nicht ueberschreiten!\n\n\t";
        gets(buffer);
    }
}
Fertig.
 
Ich habe gedacht, wenn ich es so mache, dann kann man eh nicht mehr als 30Zeichen eingeben, und es kommt ein Error ^^. Man weiß ja nie :D


Habs grad eingebaut, ich muss schon sagen, es geht perfekt :)

Big THX
 
Ich habe gedacht, wenn ich es so mache, dann kann man eh nicht mehr als 30Zeichen eingeben, und es kommt ein Error ^^.
Das Problem ist halt, dass gets() nicht weiß, wie groß der Buffer is. Und wenn ich da oben die Hausnummer mit char[5] sehe, dann kriegst du schon ein Problem, wenn ich "20-22" eingeb.

Ich muss sagen, ich hab diese ganze Funktionen, die schon fertig irgendwas einlesen nie benutzt, weil dieses Problem immer auftreten kann, egal wie groß der Buffer is.

Mein Rat: Setz dich weiterhin mit Zeigern auseinander. Du scheinst noch nicht wirklich den Durchblick zu haben, wie man mit den Sternen umgeht und was die Begriffe Speicher, Array und Zeiger verbindet.
 
Zeiger ist wirklich neuland für mich. Hast recht, kA wo da ein * hin kommt *gg* Die größe von der HausNr. setz ich mal auf 10, man weiß ja nie, was er für Hausnummern gibt.

Das ganze Projekt ist wie eine art Arbeit. Sollte man eig. in so Projekten die Eingaben pruefen, ob diese Stimmen können? Z. B. der Name nur aus Buchstaben, genauso wie der Ort? Aber ich denke immer, wenn einer irgentwo wohnt, wo es Zahlen im Ort gibt *fg* Hab so was eig. noch nie gesehn, aber das Projekt könnte ja international genutzt werden ^^
Habe gestern dafür schon Funktionen dafür gesehen, um zu Prüfen ob ein Buchstabe aus den Alphabet ist oder nicht, obs eine Zahl ist...

Oder ich werbe einfach mit Eingabe-Freiheit *g* Nur ob dem Lehrer das gefällt? :D