Kleines (Pointer)-Problem
-
Hallo ich übe gerade ein wenig und hab folgende Aufgabe gemacht:
Write a function which puts the characters in a text string in reverse order. The function should use two pinters. The only parameter of the function should be a pointer to the stringvoid Reverse(char *text[]) { unsigned short int anz = 5; // Wie bekomm ich das dynamisch ? char *a = *text, *e = *text + anz, *tmp; while (a <= e) { *tmp = *a; *a = *e; *e = *tmp; a++; e--; } } int main(int argc, char* argv[]) { char *text = "Ronald"; Reverse(&text); cout << text; return 0; }Ich bin noch neu im Pointerkram, leider hat sizeof text / sizeof text[0] nichts gebracht und auch strlen war hier nicht zu gebrauchen oder ich weis nicht wie wegen den unterschiedlichen typen. Bitte helft mir. Danke

-
Also fangen wir mal an:
1. Wenn du die Adresse text an die Funktion Reverse() uebergeben moechtest,dann brauchst du da keine Referenz mehr, d.h. du kannst das & Zeichen einfach weglassen, denn die Variable ohne den * ist schon die Adresse.
2. genuegt es, wenn du im Parameter auch nur char *text schreibst... die eckigen Klammern kannst du dir sparen.
3. Wuerde ich dafuer nicht char * benutzen sondern mir mal die STL string anschauen. ich glaube die beinhaltet schon eine Methode reverse();
hier ein kleines beispiel:
string a; cin>>a; a.reverse(); cout<<a;
-
ad 1: wo Referenz, wo?
ad 2: "die eckigen Klammern" sind der Grund für das "&" welches du für eine Referenz hältst, und natürlich sind sie unnötig
ad 3: er hat eine AUFGABE erhalten, und da es Teil der AUFGABE ist 2 Zeiger zu verwenden sollte er das wohl tun, und nicht einfach std::string::reverse oder std::reverse verwenden.@shadowmasta: mach aus "char *text[]" einfach "char* text". Und "text + anz" ist falsch, das muss "text + anz - 1" sein -- zumindest so wie du in der Schleife weitermachst muss es "text + anz - 1" sein, sonst würdest du das Nullbyte welches den String hinten abschliesst auch mit an den Anfang tauschen.
-
shadowmasta schrieb:
...
...leider hat sizeof text / sizeof text[0] nichts gebracht und auch strlen war hier nicht zu gebrauchen ...Hi,
also das hat eigentlich nichts mit C++ zu tun, sondern ist reines C
... aber ich versuche mal zu helfen:
1.) Der "sizeof-"-Trick funktioniert nur bei echten Arrays, nicht mehr, wenn sie "zu Zeigern degeneriert sind" (wie es bei der Übergabe an Funktionen immer passiert).
2.) Wieso "ist strlen() nicht zu gebrauchen" ? Ist hier das Mittel der Wahl ... und außerdem das letzte, was Dir bleibt, wenn Du die Länge nicht explizit übergeben darfst (weswegen std::string auch besser wäre
).Mal eine Frage vorab: Bist Du sicher, dass Du C einsetzen musst und nicht C++ verwenden darfst ? Andererseits steht da noch, dass man "2 Pointer" verwenden soll .... und dafür hätte man mit Verwendung eines std::strings irgendwie keinen Bedarf....hmmm.
Zum Rest hat der hustbaer schon Wesentliches gesagt:
hustbaer schrieb:
...
@shadowmasta: mach aus "char *text[]" einfach "char* text". Und "text + anz" ist falsch, das muss "text + anz - 1" sein -- zumindest so wie du in der Schleife weitermachst muss es "text + anz - 1" sein, sonst würdest du das Nullbyte welches den String hinten abschliesst auch mit an den Anfang tauschen.(nur zur weiteren Erläuterung: "text + anz" zeigt auf das Byte hinter dem letzten Zeichen: text+0 -> 1. Zeichen, text+1 -> 2. Zeichen, .... )
Gruß,
Simon2.
-
Und noch eine Ergänzung:
char* tmp;wird dir das Programm recht schnell abrauchen lassen (SegFault) - und als Zwischenvariable für den Ringtausch reicht ein normaler char völlig aus.
-
Ich hätte da noch eine kleine Verständnisfrage:
Wieso:
char *a = *text, *e = *text + anz, *tmp;und nicht
char *a = text, *e = text + anz, *tmp;Er will doch damit vergleichen, ob er am Ende vom char-array angekommen ist, oder nicht? Und da will er doch den Wert von text (also die Adresse) an die pointer a und e übergeben, und nicht etwa das, was an der Stelle im Array steht.
Was habe ich hier bez. Pointer missverstanden?
@Simon2: da steht "text string", also nicht einfach string. Von daher würde ich darauf tippen, dass, wenn sie std::string in der Schule noch nicht gesehen haben, damit ein char array gemeint ist.
-
Shinja schrieb:
Ich hätte da noch eine kleine Verständnisfrage:
Wieso:
*text...
Naja, sein Reverse bekommt ja keinen char*, sondern einen char** ... da muss man schon einmal dereferenzieren, um einen char* in die Finger zu bekommen.
Was entspricht einem "text string" besser als einstd::basic_string<char>, der std::string nunmal ist ? :pGruß,
Simon2.
-
Hallo vielen Dank für die Zahlreichen Antworten. Was ich vergessen habe zu erwähnen das Programm läuft so wie es sein soll

Trotzdem hab ich versucht euch nachzuvollziehen und ja gut es rennt auch :pvoid Reverse(char* text) { unsigned short int anz = 5; // Statisch is doch dooof :/ char *a = &text[0], *e = &text[anz]; char tmp; while (a <= e) { tmp = *a; *a = *e; *e = tmp; a++; e--; } }Aber davon mal abgesehen war die Aufgabe diese Übung zu machen und meine Frage, ob es eine Möglichkeit gibt die Länge des übergegebenen char-Pointers auszulesen. Warum das mit meinen Methoden nicht ging ist mir nun klar geworden.
Alternativ müsste ich den char bis zum Nullbyte durchgehn.
Danke an alle Erklärbären
das soll C++ sein und ich übe halt mit den Aufgaben.
-
Da ist immer noch ein * zu viel:
char *a = text, *e = text + anz-1;(und die Länge kannst du mit strlen() ermitteln).PS: Wenn es C++ sein soll, vergiss char-Pointer für den Moment und nimm dir einen std::string.
-
Nun endlich durch die Änderungen geht es nun mit strlen().
Vielen vielen Dank
In dem Buch wurde nur char behandelt und damit geht ja auch alles, wenn auch umständlicher :p
Ok ich danke euch allen nun ist diese Aufgabe gelöst.unsigned short int anz = strlen(text)-1; char *a = text, *e = text + anz;mfg

-
Auch wenn das Ergebnis dasselbe ist:
Die Länge des strings ist strlen(text) (und nicht strlen(text) - 1)
Die letzte Stelle des strings ist text + länge - 1 (und nicht text + länge)Weil: Die letzte Stelle eines 1 Zeichen langen Strings ist 0


-
Hi,
seeehr wichtig finde ich noch diesen Hinweis von CStoll, den Du unbedingt beherzigen solltest:
CStoll schrieb:
Und noch eine Ergänzung:
char* tmp;wird dir das Programm recht schnell abrauchen lassen (SegFault) ...Hier nochmal der Kontext:
shadowmasta schrieb:
...
char *text = "Ronald";Hier lässt Du text auf readonly-Speicher zeigen und hier:
shadowmasta schrieb:
...
... char *a = *text ... *a = *e;schreibst Du trotzdem rein !!
Das führt zu "undefinierten Ergebnissen", was üblicherweise verglichen wird mit dem Sprung ohne Fallschirm aus einem Flugzeug: Auch wenn beim erstem Mal ein zufällig vorbeifliegender Wildentenschwarm Deinen Fall abgebremst hat, würde ich es
a) nicht nocheinmal tun und
b) auf keinen Fall unter "Klappt doch - mach ich jetzt immer so !" verbuchen.Ferner ist das hier:
CStoll schrieb:
...
- und als Zwischenvariable für den Ringtausch reicht ein normaler char völlig aus...auch noch eine schöne Aufgabe, falls Du noch Lust auf etwas Lernen hast.
Gruß,
Simon2.
-
Hehe ja das ist mir klar aber wie du schon sagtest und auch viele andere Leute: Das Ergebnis zählt
Trotzdem danke für den Hinweis ich werde es in Zukunft an deinem Beispiel ausrichten der Sauberkeit wegen 
@CStoll: bezieht sich das noch auf den aktuellen Code ?
void Reverse(char* text) { unsigned short int anz = strlen(text); char *a = text, *e = text + anz-1; char tmp; while (a <= e) { tmp = *a; *a = *e; *e = tmp; a++; e--; } }PS. So tief bin ich auch nicht in der Materie aber ich lasse mich gerne berichtigen
