C++ Getter/Setter Problem mit char Variable

Manda

Erfahrenes Mitglied
Hallo zusammen,
ich möchte in eine Variable char name[10] einen Namen speichern. Diese ist im

Private: char name[10] deklariert.

Dafür gibt es getter/setter:
C++:
char GeomObjekt::getName()
{
	return name[10]; //UNSICHER OB DAS KORREKT IST!
}

void GeomObjekt::setName(char Name[10])
{
	strcpy(name, Name);
}

Nun greife ich darauf zu und möchte einen Namen speichern. So etwa:
C++:
	objekt[1].setName("Punkt");
        objekt[2].setName("Ecke");
//Habe mehrere Objekte

Hier möchte ich das auch ausgeben:
C++:
for(int i=1; i<=anzahl; i++)
	{
		eingabe++;
		cout << endl;
		cout << eingabe << ". Objekt ist ein ";
		cout << objekt[i].getName();
        }

Nur kriege ich keinen Namen ausgegeben, sondern irgendwelche Sonderzeichen.
Ich habe schon folgendes versucht in der getter von Name:
return (char)name;

Das ging allerdings auch nicht. Hättet ihr einen Tip wie ich den Namen ausgeben könnte? Oder ist mein Getter bzw Setter falsch?

Gruß
Manda
 
Hi

1: Dein getter braucht den Returnwert "char *"
2: Beim Return drinnen sollte name zurückgegeben werden - nicht das 11. Byte!
...3: Beim setter wäre eine Überprüfung der Stringlänge nicht schlecht, es gibt auch Namen mit mehr als 10 Buchstaben
zB
if(strlen(Name)<=9)
strcpy...

Gruß
 
Hi. Ob du nun einen Zeiger auf char oder char direkt ausgiebst ist im prinziep egal. Ich würd (damit es einfacher ist für dich ohne Zeiger zu arbeiten)
deine get Methode sollte etwa so aussehen:
C++:
char GeomObjekt::getName()
{
    return name;
}
So gibst das Komplette Array zurück, So wie du es hattest war es nur das lezte zeichen.

Die Set Methode könntest du so basteln:
C++:
void GeomObjekt::setName(char Name[10])
{
    strcpy(name, Name);
}
Dan kannst du die Zeichenfolge eigentlich auch so ausgeben wie du es hattest. Objekt, punktoperator, variable.

Was jezt noch sein könnte ist, dass der String nicht sauber abgeschlossen ist, das heist, dass deine Ausgabe so ausehen würde:
C++:
Ausgabe: Ecke§$&(%/%
Halt so, dass der Rest von dem Zeichen Array, welchen du nicht gefüllt hast mit datenmüll zu ist. Deshalb, wenn du mit char und nicht mit Strings arbeitest immer sauber abschliesen. Etwa so:
C++:
void GeomObjekt::setName(char Name[10])
{
    strcpy(name, Name);
name += "\0"; //bin mir hier von der Syntax nicht ganz sicher
}
Damit ist hinter deiner Eingabe ein \0 (Backslash-Null), dieses kann analysiert werden, und somit das Stringende herausgefunden werden. Cout überprüft glaube ich automatisch ob ein \0 vorhanden ist. Bei Printf muss es abgefangen werden. Deswegen der Vorteil von string oder CString: Das Ende wird automatisch sauber abgeschöosen, und du brauchst dich nicht darum kümmern;)

MfG Dimitrij B.
 
Zuletzt bearbeitet von einem Moderator:
Danke für die Antworten!
Ich habe es bisschen anders gemacht. Benutze nun den Datentyp string.
So etwa:
std::string name;

Das schien mir am leichtesten.
Gruß

Manda
 
@Marschal:
Dein getter hat den Falschen Returntyp
Es ist NICHT egal, ob man einen char oder einen char-Pointer nimmt.

Zweitens ist bei private (wie im ersten Post angegeben) nichts mit Objekt-Punkt-Variable zu machen

Und
name+='\0';
ist Unsinn und ist hier auch vollkommen unnötig
strcpy kann das genau wie euer "toller" string auch ganz alleine...

PS: Wenn keine abschließende '\0' vorhanden ist, macht cout genau den gleichen Blödsinn wie printf
Woher soll cout denn wissen, ob die nächste '\0' im RAM eigentlich noch zu deinem char-Array gehört oder nicht?
 
Zuletzt bearbeitet:
@sheel
Ich mein ich habe erwähnt, ich bin mir nicht sicher Diesbezüglich...Desshalb ist es sehr erfreulich, dass du mich in diesem Punkt freundlih korregiert hast.
Private hatt ich überlesen. Dan ist klar, dass man die Variable über die Get-Methode erhällt, sonst wäre der spas ja sinnfrei.

@MandaSchön, dass du dich für die String-Klasse entschieden hast. Ist zwar einfacher, doch ich würde dich trozem empfehlen das ganze mal auch mit einem Char-Array durchzuspielen;) Übungshalbar:)

@Shell
Und
name+='\0';
ist Unsinn und ist hier auch vollkommen unnötig
strcpy kann das genau wie euer "toller" string auch ganz alleine...
PS: Wenn keine abschließende '\0' vorhanden ist, macht cout genau den gleichen Blödsinn wie printf
Woher soll cout denn wissen, ob die nächste '\0' im RAM eigentlich noch zu deinem char-Array gehört oder nicht?
lies doch bitte genuer, ehe du dich der Kritik vergreifst;)
Was ich gesagt hatte:
Damit ist hinter deiner Eingabe ein \0 (Backslash-Null), dieses kann analysiert werden, und somit das Stringende herausgefunden werden. Cout überprüft glaube ich automatisch ob ein \0 vorhanden ist. Bei Printf muss es abgefangen werden. Deswegen der Vorteil von string oder CString: Das Ende wird automatisch sauber abgeschöosen, und du brauchst dich nicht darum kümmern
Cout oder printf weis garnichts mir einem backslash-Null anzufangen, doch abfragen oder abfangenmeint eine IF-Abfrage in der dies geschiet!...

MfG Dimitrij B.

EDIT: ach ja...
Dein getter hat den Falschen Returntyp
Es ist NICHT egal, ob man einen char oder einen char-Pointer nimmt.
Wo hat den meine Get-Methode einen falschen Rückgabewert bitte? Wenn du mir solches schon vorwirfst, so habe auch den anstallt meine aus deiner Sicht falsche Aussage zu korregieren, ansonsten sehe ich keinen Grund einfach rumzumeckern. JEder Programmiert andesr, wenn dir mein Style nicht passt, so ists dein Problem, Shell weis, so denke ich, etwas mit meinen Tips anzufangen;)
 
Zuletzt bearbeitet:
Wo hat den meine Get-Methode einen falschen Rückgabewert bitte? Wenn du mir solches schon vorwirfst, so habe auch den anstallt meine aus deiner Sicht falsche Aussage zu korregieren, ansonsten sehe ich keinen Grund einfach rumzumeckern. JEder Programmiert andesr, wenn dir mein Style nicht passt, so ists dein Problem, Shell weis, so denke ich, etwas mit meinen Tips anzufangen;)
Die Wahl zwischen char und char * (besser noch const char *) hat nichts mit dem Programmierstil zu tun, da die Semantik eine komplett andere ist. Ein vernünftiger Compiler weist deinen Quellcode wegen der undefinierten Konvertierung von char[10] in char vermutlich sowieso zurück.

@Manda: Schön, dass du es mit std::string hinbekommen hast :) Wie sehen denn deine Getter und Setter jetzt aus? Ich frage nur nach, weil man da trotzdem noch einiges falsch/suboptimal machen kann (z.B. unerwünschte Mehrfachkopien).

Grüße, Matthias
 
Die Wahl zwischen char und char * (besser noch const char *) hat nichts mit dem Programmierstil zu tun, da die Semantik eine komplett andere ist. Ein vernünftiger Compiler weist deinen Quellcode wegen der undefinierten Konvertierung von char[10] in char vermutlich sowieso zurück.
Grüße, Matthias
Das nenne ich konstruktiv;) Hab ich nichts auszusetzen, hatte keinen Kompiler griffbereit, an dem ich das hätte testen können.
Ich arbeite grundsätzlich mit Pointern.
Leztendlich ist die Logik ist entscheident, wie man es leztendlich umsezt ist doch im Prinziep wurscht;)
 
Hast du es nicht gelesen?
Du bekommst einen Kompilerfehler, die Umsetzung ist NICHT wurscht
...
 
Hallo nochmal. Hätte noch einige ergänzenden Fragen.

@Reitinger: Die getter/setter sehen so aus:
C++:
std::string GeomObjekt::getName()
{
	return std::string(name);
}

void GeomObjekt::setName(std::string Name)
{
	name = Name;
}

------------------------------------

Hätte aber ein anderes Problem jetzt, wenn ihr auch dafür ein Auge habt wäre es sehr nett?!
Es geht um Flächenberechnung (übung mit getter/setter und c++).
Ich habe ein Oberklasse: GeomObjekt . Diese hat 2 Unterklassen (Kreis und Rechteck).

Hier die Erstellung der Objekte:
C++:
GeomObjekt objekt[3]; 
    GeomObjekt objektA;
    Rechteck   rechteck[1];
    Kreis      kreis[1];

    cout << "Anzahl der Objekte: ";
    cin  >> anzahl;   
    cout << endl;
Ich weis das ich 3 FESTE Objekte habe. Ich kenne mich mit Listen nicht aus. Ich wollte abfragen, wieviele Objekte denn erstellt werden sollen. Und anhand der Eingabe, dann meine Objekte erstellen.
Erstmal hab ich ja nur 3.

Hier lese ich das ein:
C++:
do
    {
        eingabe++;       
        cout << endl;
        cout << eingabe << ". Objekt ist ein: ";
        cin  >> auswahl;
       
        if(auswahl == 'p')
        {
            objekt[1].setName("Punkt");
            cout << "Punkt" <<endl;
            cout << "X = ";
            cin  >> x;       
            cout << "Y = ";
            cin  >> y;
            cout << endl;
            objekt[1].setXpos(x);
            objekt[1].setYpos(y);
            U = objekt[1].umfangBerechnung(0, 0, 0);
            objekt[1].setU(U);
            A = objekt[1].flaechenBerechnung(0, 0, 0);
            objekt[1].setAFlaeche(A);
        }

Das gleiche mache ich dann für 2.Objekt (Quadrat als bsp.). Lese ich jetzt aber ein Rechteck ein(was eine Unterklasse ist):
C++:
else if(auswahl == 'r')
        {
            rechteck[1].setName("Rechteck");
            cout << "Rechteck" << endl;
            cout << "X = ";
            cin  >> x;
            cout << "Y = ";
            cin  >> y;
            cout << "a = ";
            cin  >> a;
            cout << "b = ";
            cin  >> b;
            cout << endl;
           
            rechteck[1].setXpos(x);           
            rechteck[1].setYpos(y);
            rechteck[1].setAR(a);
            rechteck[1].setBR(b);
            U = rechteck[1].umfangBerechnung(rechteck[1].getAR(), rechteck[1].getBR(), 0);
            rechteck[1].setU(U);
            A = rechteck[1].flaechenBerechnung(rechteck[1].getAR(), rechteck[1].getBR(), 0);
            rechteck[1].setAFlaeche(A);           
        }

while(eingabe < anzahl);//hier geht die while zu ende

Ich wusste nicht ob ich für rechteck-Objekt ein Array nehmen sollte. Es kann ja sein, dass ich merhere Rechtecke habe. Dann kommt wieder das Problem mit dem List/Vector.

Kurz noch die Ausgabe, welche allerdings mir die meisten Kopfschmerzen bereitet!
C++:
eingabe = 0;
    cout << "Folgende Objekte wurden eingegeben:" << endl;   
    for(int i=1; i<=anzahl; i++)
    {
        eingabe++;
        if(objekt <= 0)
        {
            cout << "Keine Objekte eingegeben...";
            exit(1);
        }
        else
        {           
            cout << endl;
            cout << eingabe << ". Objekt ist ein ";
            cout << objekt[i].getName();
            cout << ":";
            cout << " P(";
            cout << objekt[i].getXpos();
            cout << ",";
            cout << objekt[i].getYpos();
            cout << ")" << endl;
            cout << "U = " << objekt[i].getU() << endl;
            cout << "A = " << objekt[i].getAFlaeche() << endl;
        }
}

Ich weis auch nicht, wie ich das mit Rechteck/Kreis ausgeben könnte. Da sie ja nicht vom Typ GeomObjekt sind.

Sorry Leute, sind viele kleine Probleme wo ich nicht weiter komme. Hoffe sehr das einer von ich mir helfen könnte!

Schönen Gruß

Manda
 
Zurück