String in String kopieren.
-
Hallo, habe in der Schule folgende Aufgabe bekommen, an der ich scheitere, da ich noch Anfänger bin:
Schreiben Sie eine Funktion
void copyAndInvertString(char *s1, char *s2);
die den String in s1 in den String s2 kopiert, beginnend allerdings mit dem letzten Zeichen in st1. („TestString“ würde damit zu „gnirtStseT“)Deklarieren Sie die char-Felder st3 und st4 entsprechend im Hauptprogramm, initialisieren Sie st3, rufen Sie copyAndInvertString korrekt auf und geben Sie st4 im Hauptprogramm aus.
Unser Lehrer hats uns so erklärt: Bei s1 müssen wir von hinten anfangen. Also den letzten Buchstaben an die erste Stelle von s2 kopieren usw.. (mit for(..))
Kann mir da bitte jemand helfen?
-
baembaem schrieb:
Schreiben Sie eine Funktion
void copyAndInvertString(char *s1, char *s2);
die den String in s1 in den String s2 kopiert, beginnend allerdings mit dem letzten Zeichen in st1. („TestString“ würde damit zu „gnirtStseT“)Autsch. Mein Beileid. So eine Übung würde ich nicht mit "modernem C++" in Verbindung bringen. Und selbst wenn Dein Lehrer C++ kann (und nicht nur C) ist diese Herangehensweise didaktisch meiner Meinung nach nicht besonders schlau...
baembaem schrieb:
Deklarieren Sie die char-Felder st3 und st4 entsprechend im Hauptprogramm, initialisieren Sie st3, rufen Sie copyAndInvertString korrekt auf und geben Sie st4 im Hauptprogramm aus.
Unser Lehrer hats uns so erklärt: Bei s1 müssen wir von hinten anfangen. Also den letzten Buchstaben an die erste Stelle von s2 kopieren usw.. (mit for(..))
Kann mir da bitte jemand helfen?
Wo hakt's denn? Zeig doch mal...
-
Ja also eig scheiter ich da gleich von Anfang an

habs nur soweit:
void copyAndInvertString(char *s1, char *s2) {
int i;und dann kommt ja die Schleife
for(i=?;...)da weis ich auch nicht was rein soll

man muss da ja von hinten anfangen, aber wie?
-
Die Aufgabenstellung deutet eindeutig auf native C hin. Kann man zur Übung für Schleifen und C-Strings durchaus machen. Wozu aber werden 4 C-Strings verlangt, wenn nur 2 erforderlich sind?
Hinweise zur Lösung:
--> Länge des übergebenen char-Feldes s1 ermitteln mit len = strlen()
--> Schleife mit 2 Scheifenzählern i (rückwärts), j (vorwärts) einrichten
--> s2[j] = s1[i];
--> abschliessendes Nullzeichen '\0' in s2 anfügenFang mit diesen Hinweisen die Funktion an und zeige den Code. Dann halfen wir weiter!
-
#include <iostream> #include <string> #include <cstring> #include <algorithm> void get_reversed(const char* b, char *c) { std::string a(b); std::reverse(a.begin(), a.end()); strcpy(c,a.c_str()); } int main() { using std::cout; cout << "String 1: "; std::string str1; std::getline(std::cin, str1); char* a = new char[str1.length()]; get_reversed(str1.c_str(), a); cout << "String 2 ist " << a << "\n\n"; delete []a; }Das ist jetzt C++ mit C-Strings.
-
void copyAndInvertString(char const* s1, char *s2){ { std::string str(s1); std::reverse(str.begin(), str.end()); s2[str.copy(s2, str.length())] = 0; }So. Und wehe dein Lehrer beschwert sich.

-
Ethon schrieb:
void copyAndInvertString(char const* s1, char *s2){ { std::string str(s1); std::reverse(str.begin(), str.end()); s2[str.copy(s2, str.length())] = 0; }So. Und wehe dein Lehrer beschwert sich.

Haha :xmas1:
Edit: Ich hab das nicht abgeguckt, aber meins finde ich schöner
-
Ich sollte aufhören Tabs zu öffnen und sie zu vergessen .

-
void change(char *s1,char *s2) { int i,j,len; len = strlen(s1); for(i=len-1,j=0;j<len;i--,j++) s2[j]=s1[i]; s2[len] = '\0'; }Und nun such dir aus, was du haben willst. Sage aber nicht deinem Lehrer, was wir über ihn denken!
Sollte der Lehrer sich an i-- und j++ stossen, nimmst du i=i-1 und j=j+1
-
Na super, auch wenn die Highlevel-Code-Gurus unter euch solche Basics als nicht lohnenswerte Übungsaufgabe erachten, so kann sie für den Anfänger sehr wohl von großem Nutzen sein.
Wieso hier der std::string ins Spiel gebracht wird, verstehe ich auch nicht, bernibutt's Lösung ist schon okay (mal abgesehen davon, dass Variablen auch sofort initialisiert werden sollten) - aber darauf wäre der TE mit bernie's Tipps eventuell auch gekommen.
-
Gut, dann eben ohne std::string:
void copyAndInvertString(char const* s1, char *s2){ { strcpy(s2, s1); std::reverse(s2, s2 + strlen(s2)); }
-
Ich Idiot. So gehts natürlich:
void copyAndInvertString(char const* s1, char *s2){ { std::reverse_copy(s1, s1 + strlen(s1), s2); }
-
berniebutt schrieb:
void change(char *s1,char *s2) { int i,j,len; len = strlen(s1); for(i=len-1,j=0;j<len;i--,j++) s2[j]=s1[i]; s2[len] = '\0'; }Und nun such dir aus, was du haben willst. Sage aber nicht deinem Lehrer, was wir über ihn denken!
Sollte der Lehrer sich an i-- und j++ stossen, nimmst du i=i-1 und j=j+1Die anderen Lösungen versteh ich nicht wirklich

Habs auch schon nach deiner ersten Antwort versucht..
Hatte alles außer das s2[len] = '\0';
Aber jetzt funktionierts, danke!
Und danke auch für die anderen Antworten^^
-
na super schrieb:
Na super, auch wenn die Highlevel-Code-Gurus unter euch solche Basics als nicht lohnenswerte Übungsaufgabe erachten, so kann sie für den Anfänger sehr wohl von großem Nutzen sein.
Wieso hier der std::string ins Spiel gebracht wird, verstehe ich auch nicht, bernibutt's Lösung ist schon okay (mal abgesehen davon, dass Variablen auch sofort initialisiert werden sollten) - aber darauf wäre der TE mit bernie's Tipps eventuell auch gekommen.
Wenn er C lernen soll, soll er. C++ ist gerade deswegen besser, weil du dich um so einen Kleinkram nicht kümmern musst. Das ist z.B. schon ein Höhepunkt an Leistung:
std::string get_reversed(std::string ref) { std::reverse(ref.begin(), ref.end()); return ref; }
-
Ethon__ schrieb:
Gut, dann eben ohne std::string:
void copyAndInvertString(char const* s1, char *s2){ { strcpy(s2, s1); std::reverse(s2, s2 + strlen(s2)); }Das Compiliert nicht, das muss ich nicht überprüfen (fpermissive) :xmas1:
Kenn ich auswendigedit: Oh, doch! Bei mir ging es aber nicht, als ich es versuchte
-
Hmm? Das ist komplett standardkonform, da sollte der GCC nicht meckern. (fpermissive gibts ja auch nur bei undefiniertem Verhalten)
Trotzdem ist reverse_copy nochmal deutlich eleganter, ich sollte mir endlich mal merken was alles in algorithm drin ist.
-
Nehmt's mir nicht übel, aber ich habe gerade Lust, eine C++11 Version zu posten

string flip(string x) { std::reverse(x.begin(),x.end()); return x; }... nun wieder ekeliges C ohne ++ ...
baembaem schrieb:
Ja also eig scheiter ich da gleich von Anfang an

habs nur soweit:
void copyAndInvertString(char *s1, char *s2) {
int i;und dann kommt ja die Schleife
for(i=?;...)da weis ich auch nicht was rein soll

man muss da ja von hinten anfangen, aber wie?Da musst Du Dich mal ein bisschen mehr anstrengen. Überleg doch erstmal, was der Rechner da eigentlich zu tun hat und dann im nächsten Schritt erst, wie man das aufzuschreiben hat. Auf konkrete Fragen, deren Antwort nicht gleich eine komplette Lösung Deiner Hausaufgabe wäre, antworte ich gern.
/// kopiert Zeichenkette (gegeben durch Zeiger s1) /// in ein char-Array (gegeben durch Zeiger s2) /// in umgekehrter Reihenfolge. Achtung: Das Array /// muss natürlich groß genug sein! void copyAndInvertString(const char *s1, char *s2) { // s1 ist hier ein Zeiger, der auf das erste Zeichen von "ollaH" zeigt. // Also, s1[0] -> 'o' // s1[1] -> 'l' // ............ // s1[4] -> 'H' // s1[5] -> 0 (Nullterminierung. So wissen wir, // wie lang die Zeichenkette ist) ... // Ziel (für _dieses_ Beispiel): // s2[0] -> 'H' // s2[1] -> 'a' // ............ // s2[4] -> 'o' // s2[5] -> 0 (Nullterminierung) } int main() { static const char text1[] = "ollaH"; char text2[99]; // muss mindestens Platz für 6 Elemente haben // (5 Buchstaben und die Nullterminierung) copyAndInvertString(text1,text2); ... return 0; }Nun kann die Zeichenkette natürlich länger oder kürzer sein. Die Funktion sollte dann immer noch funktionieren. Was kennst Du denn für string-Funktionen, die die Standardbibliothek bereitstellt? Vielleicht ist da etwas bei, was Dir hilft...
Cheers!
kk
-
Wenn wir so weit schon sind:
std::string flip(std::string const &s) { return std::string(s.rbegin(), s.rend()); }
-
seldon schrieb:
Wenn wir so weit schon sind:
std::string flip(std::string const &s) { return std::string(s.rbegin(), s.rend()); }Wenn das Argument von flip allerdings ein Rvalue ist, wird bei Dir unnötig kopiert. Trau Dich, bei move-optimierten Typen pass/return-by-value einzusetzen.

Wenn's jetzt super effizient sein soll, dann vielleicht auch per Überladung:
std::string flip(std::string const &s) { return std::string(s.rbegin(), s.rend()); } std::string flip(std::string &&s) { std::reverse(s.begin(),s.end()); return std::move(s); }Aber meine erste Version gefällt mir da immer noch am besten.

Edit: Mist! Ich sehe gerade, baembaem hat sich mit einer vorgefertigten Lösung zufrieden gegeben. Echt schade...
Cheers!
kk
-
na super schrieb:
Na super, auch wenn die Highlevel-Code-Gurus unter euch solche Basics als nicht lohnenswerte Übungsaufgabe erachten, so kann sie für den Anfänger sehr wohl von großem Nutzen sein.
Wieso hier der std::string ins Spiel gebracht wird, verstehe ich auch nicht, bernibutt's Lösung ist schon okay (mal abgesehen davon, dass Variablen auch sofort initialisiert werden sollten) - aber darauf wäre der TE mit bernie's Tipps eventuell auch gekommen.
Diese Frage war wohl im falschen Unterforum gelandet. Also sind viele auf std::string herumgeritten ohne die vorgesetzte Aufgabe mit einer for-Schleife berücksichtigt zu haben. Ist ansonsten eine schöne Übungsaufgabe für eine for-Schleife und für C-Strings. High-Level-Gurus brauchen keine C-Strings und können sich schwer auf das erkennbare Wissen eines Anfängers einstellen. C-Basics können aber niemand schaden, auch den High-Level-Gurus nicht! Der TE konnte eure Lösungen nicht verstehen, weil er in C und nicht in C++ lernt. Nur deswegen habe ich die vollständige Lösung in C nachgeschoben.
daddeldu! :p