Frage zu strings als übergabe/rückgabewerte und srtcpy
-
Edit:
1.- Was ist string?
Eine Zeichenkette vom Typ Char.
2.- Warum gibt’s bei text::text(char*) kein const?
Ich hab const eingefügt und die Warnung in Zeile 98 ist verschwunden den grung versteh ich aber nicht. bitte um erklärung.
3.- Wo ist der Zuweisungsoperator? (Verletzung der Dreierregel)
Hab einen geschrieben.
Ist er richtig und sinnvol? (Dreierregel war mir nicht bekannt.)
4.- get/setchar hätte man als operator[] machen sollen.
Wie ist das gemeint? wie kann ich beispiele finden?
5.- Ein Defaultconstructor, der schon Speicher reserviert, ist doof in diesem Fall.
Wies doof und ist die änderung jetzt sinnvoll?
6.- Warum sprichst Du von „C-Strings“, wenn „string“ im Spiel ist?
Hab nichs gefunden was es mir verständlich erklärt wie man cstrings und srtings unterscheiden kann bzw cstrings benutzt.
Der Aufgabenbeschreibung nach muss ich cstring's benutzen. Link oder Beispiel zur Erklärung?
7.- Die Fehlerbehandlung in setchar ist unüblich. Mach ein assert drauß oder schmeiß eine Außnahme.
Da hab ich keine Fehlermeldung. Meinst du eventuel was anderes?
8.- Dieses deprecated-Ding ist kein Fehler sondern eine Warnung.
Sorry mein Fehler. Aber wie bekomme ich sie weg?
Und was ist mit der Fehlermeldung in Zeile 105
strcpy(tx2, t2.getTxt());--------------
Hallo Leute,
ich brauch mal wieder fachmännischen Rat.
Ich hab eine Klasse geschrieben die zum größten Teil das macht was ich will.Allerdings hab ich paar Probleme die ich nicht lösen kann.
Es betrifft die Methode getTxt() den string als Rückgabewert ist sie richtig geschrieben?
Den String Copy in der Zeile 95. Da steh ich irgendwie kommplet auf dem Schlauch.
Die Übergabe an die Methode setTxt() (Zeile 98) und den Konstruktor text::text(char *text) (Zeile 35).Könnt ihr mir bitte mal die Fehler erklären.
Danke
---------------#include <iostream> #include <cstring> using namespace std; class text{ public: unsigned int length;//Länge des Textes ohne das abschließende \0-Zeichen char *txt;//Dynamisches Zeichen-array, in dem der Text und das \0-zeichen gespeichert sind. //Standar-Konstruktor text(); //Ein Konstrucktor, dem ein C-String(char-Array) übergeben wird, und der damit ein entsprechendes Text-Objekt erstellt. text(const char *text); //Copy-Konstrucktor text(const text &kopie); //Zuweisungsoperator (Klasse) text operator =(const text &t); //Destruktor ~text(); //der interne Text wird als C-String zurückgegeben. string getTxt(); //der vorhandene Text wird freigegeben und der übergebene C-string wird als neuer dynamischer Text intern gespeichert. lenght anpassen void setTxt(char *neuertxt); //rückgabe von length int getLength(); //Rückgabe des zeichens im Text, das durch die Übergabe Position ausgewählt wurde. char getCharAt(unsigned int pos); //ein übergebenes zeichen überschreibt an der übergebenen Psition das alte Zeichen void setCharAt(char zeichen,unsigned int pos); }; //Standar-Konstruktor text::text(){ length=0; //txt = new char[1]; }; //Konstruktor dem ein C-string übergeben wird text::text(const char *text){ length=strlen(text); txt=new char[strlen(text)+1]; strcpy(txt, text); } //Kopie-Konstructor text::text(const text& kopie){ txt = new char[kopie.length+1]; strcpy(txt, kopie.txt); length=kopie.length; } //Zuweisungsoperator (Klasse) text text::operator =(const text& t){ text temp; length=t.length; txt = new char[temp.length+1]; strcpy(temp.txt, t.txt); return temp; } //Destruktor text::~text(){ delete[] txt; } //der interne Text wird als C-String zurückgegeben string text::getTxt(){ return string(txt); } //der vorhandene Text wird freigegeben und der übergebene C-string wird als neuer dynamischer Text intern gespeichert. lenght anpassen void text::setTxt(char *neuertxt){ delete[] txt; txt=new char[strlen(neuertxt)+1]; strcpy(txt, neuertxt); length=strlen(txt); } //rückgabe von length int text::getLength(){ return length; } //Rückgabe des zeichens im Text, das durch die Übergabe Position ausgewählt wurde. char text::getCharAt(unsigned int pos){ if(pos >= length){ cerr<< "Positionsfehler"<<endl; return '\0'; } else return txt[pos]; } //ein übergebenes zeichen überschreibt an der übergebenen Psition das alte Zeichen void text::setCharAt(char zeichen,unsigned int pos){ if (pos>= length) cerr<<"Positionsfehler beim Zeichensetzen"<<endl; else{ txt[pos]=zeichen; } } int main() { text t1, t2("TEXT"); text t3=t2; cout<< t1.txt<<endl; cout<< t2.txt<<endl; cout<< t3.txt<<endl; //getTxt char tx2[10]; strcpy(tx2, t2.getTxt());//fehler: cannot convert 'char**' to 'char*' for argument '1' to 'char* strcpy(char*, const char*)' //setTxt test t3.setTxt("abcdefg");//Fehlermeldung: deprecated conversion from string constant to 'char*' //getLength test int l; l=t2.getLength(); //getCharAt test char Z; Z=t3.getCharAt(5); //setChatAt test t3.setCharAt('D', 1); cout<< t3.txt <<endl; return 0; }
-
Alex4nder schrieb:
char *tx2[10];Das deklariert ein Array von zehn
char-Zeigern.
Nimm einfach den Stern weg, um einchar-Array zu erhalten.
Was willst du damit erreichen?
-
- deine spezialisierten Konstruktoren erzeugen alle ein Speicherleck
- verwendeunsignedDatentypen, wenn sie Sinn machen. Das ist bei dir praktisch immer der Fall, dann ersparst du dir auch die Überprüfungen auf > 0.
- getLenght ist falsch geschrieben (oder ist das eine Altlast
?)
-
- Was ist string?
- Warum gibt’s bei text::text(char*) kein const?
- Wo ist der Zuweisungsoperator? (Verletzung der Dreierregel)
- get/setchar hätte man als operator[] machen sollen.
- Ein Defaultconstructor, der schon Speicher reserviert, ist doof in diesem Fall.
- Warum sprichst Du von „C-Strings“, wenn „string“ im Spiel ist?
- Die Fehlerbehandlung in setchar ist unüblich. Mach ein assert drauß oder schmeiß eine Außnahme.
- Dieses deprecated-Ding ist kein Fehler sondern eine Warnung.
-
Alex4nder schrieb:
Edit:
1.- Was ist string?
Eine Zeichenkette vom Typ Char.
Du verwendest diesen Namen im Quellcode, ohne dass es dazu eine Deklaration oder Definition gibt. Was ist string? Ein eigener typedef oder fällt da std::string irgendwie vom Himmel?
Alex4nder schrieb:
- Warum gibt’s bei text::text(char*) kein const?
Ich hab const eingefügt und die Warnung in Zeile 98 ist verschwunden den grung versteh ich aber nicht. bitte um erklärung.
Recherchiere "const correctness"
Recherchiere "string literal"Alex4nder schrieb:
- Wo ist der Zuweisungsoperator? (Verletzung der Dreierregel)
Hab einen geschrieben.
Ist er richtig und sinnvol? (Dreierregel war mir nicht bekannt.)Habe ich mir jetzt nicht nochmal angeguckt.
Alex4nder schrieb:
- get/setchar hätte man als operator[] machen sollen.
Wie ist das gemeint? wie kann ich beispiele finden?
Wenn Du nicht weißt, was ich damit meine, dann ist das auch nicht so wichtig. Stichwort "operator overloading".
Alex4nder schrieb:
- Ein Defaultconstructor, der schon Speicher reserviert, ist doof in diesem Fall.
Wies doof und ist die änderung jetzt sinnvoll?
Defaultkonstruktoren von Containern sollten meiner Meinung nach ohne Freispeicherreservierungen auskommen, sofern möglich. Das ist eine reine Performanzsache. Kein Fehler.
Alex4nder schrieb:
- Warum sprichst Du von „C-Strings“, wenn „string“ im Spiel ist?
Hab nichs gefunden was es mir verständlich erklärt wie man cstrings und srtings unterscheiden kann bzw cstrings benutzt.
Der Aufgabenbeschreibung nach muss ich cstring's benutzen. Link oder Beispiel zur Erklärung?Mit „C-String“ sind hintereinander im Speicher liegende Zeichen (char) gemeint, wobei das Ende mit einer '\0' markiert wird (Nullterminator). Oft wird auch ein Zeiger selbst, der auf das erste Zeichen einer solchen nullterminierten Zeichenkette zeigt, „C-String“ genannt (leider).
Das Wort „string“, sofern Du es genau so schreibst (klein, ohne Plural-s) assoziere ich mit dem benutzerdefinierten Typen std::string, der dazu da ist „richtige“ String-Variablen zu deklarieren.
Bei großgeschriebenen „String“ oder „strings“ (mit Plural-s) gehe ich davon aus, dass hier kein C++ Typ gemeint ist, sondern allgemein das Konzept einer Zeichenkette.
In Deinem Programm fällt der Datentyp „string“ vom Himmel. Der C++ Sprachkern kennt das nicht. Aber std::string gibt es in der Standardbibliothek. Dazu müsste man sich aber per #include <string> die Definition davon holen. Möglicherweise hast Du einfach Glück gehabt, dass irgend ein anderer Header noch <string> inkludiert hat und Dir deswegen std::string zu Verfügung steht. Ich bin mir sicher, dass das bei mir (mit dem GCC Compiler) nicht funktionieren wird. Du kannst Dich nämlich im Allgemeinen nicht darauf verlassen, was andere Standard-Header noch so alles „importieren“.
Mir fehlt auch irgendwie die Information, warum Du eine solche Klasse geschrieben hast. Zur Übung? Oder weil Du noch nicht weißt, dass std::string in etwa das macht, was Du mit Deiner Klasse versuchst?
Alex4nder schrieb:
- Die Fehlerbehandlung in setchar ist unüblich. Mach ein assert drauß oder schmeiß eine Außnahme.
Da hab ich keine Fehlermeldung. Meinst du eventuel was anderes?
Du behandelst da selbst einen Benutzerfehler indem Du eine Fehlermeldung ausgibst. Das ist unüblich. Da nimmt man eher das assert-Macro für (aus #include <cassert>) oder man wirft eine Ausnahme per throw.
P.S.: Mir ist vorhin erst aufgefallen, dass Du per Edit im Originalpost geantwortet hast, ohne eine Nachricht an den Thread zu hängen. Das macht es für einen Leser schwierig, die Diskussion zu verfolgen. Neue Infos werden dann auch leicht übersehen.
-
krümelkacker schrieb:
Oft wird auch ein Zeiger selbst, der auf das erste Zeichen einer solchen nullterminierten Zeichenkette zeigt, „C-String“ genannt (leider).
Ist das jetzt ein C-String oder ein Char-Pointer (letzteres würd' ich sagen)?
"Hello World of Warcraft!"
-
Hacker schrieb:
Ist das jetzt ein C-String oder ein Char-Pointer (letzteres würd' ich sagen)?
"Hello World of Warcraft!"Ich würde einfach „Stringliteral“ sagen. Als solches ist es ein Lvalue-Ausdruck vom Typ „array of const char“ mit einer Nullterminierung am Ende. Es kann implizit zu einem Zeigerwert (Adresse) konvertiert werden. Ob diese Konvertierung aber stattfindet, hängt vom Kontext ab. Und da sie quasi unsichtbar ist (kein dediziertes Syntaxelement), kann man sich zumindest darüber streiten, ob man diese Konvertierung mitzählen muss oder nicht, wenn man den Typ dieses Ausdrucks diskutiert.