Einer Char-Zeichenkette ein Leerzeichen hinzufügen.



  • Guten Morgen,
    ich arbeite zurzeit das Buch "C++ - Objektorientiertes Programmieren von Anfang an" von Helmut Erlenkötter durch und habe Schwierigkeiten mit einer Übung.
    Mein Programm soll zwei Zeichenketten einlesen, zusammenfügen & ausgeben.

    Der Code:
    [code="cpp"]
    char ergebnis[20], eingabe [20];
    int laenge;
    cout << "Wort eingeben\n";
    cin >> eingabe;
    strcpy(ergebnis, eingabe); // eingabe wird in ergebnis gespeichert
    cout << "\n2. Wort eingeben\n";
    cin >> eingabe;
    laenge = strlen(ergebnis); // Länge von ergebnis wird ermittelt
    ergebnis [laenge] = 32;
    strcat (ergebnis, eingabe); // Zeichenketten werden zusammengefügt in ergebnis
    cout << "\n" << ergebnis << "\n";
    system ("\nPAUSE");
    [/code]

    Es klappt alles bis auf die Tatsache, dass bei der Ausgabe ein Leerzeichen fehlt. Wenn ich "Hallo" und "Welt" eingebe, erscheint HalloWelt.
    Also wollte ich mit der markierten Zeile ein Leerzeichen hinzufügen, was mir aber nicht ganz gelingt.
    Das Programm lässt sich zwar ausführen, allerdings bekomme ich als Ausgabe Hallo Welt zwar mit Leertaste, aber zwischen der Leertaste und "Welt" stehen noch eine Menge komischer Sonderzeichen.
    Ich habe auch versucht mittels der strlen-Funktion die Länge jeweils ohne und mit Leerzeichen zu ermitteln, um zu sehen ob das Leerzeichen korrekt eingefügt wurde, aber überraschenderweise war das Ergebnis bei beidem gleich (zählt die strlen-Funktion keine Leerzeichen?).

    Ich habe auch nach den Lösungen des Buches gesucht, allerdings wurde ich nicht fündig.



  • #include <iostream>
    #include <string>
    using namespace std;
    
    int main()
    {
    	std::string s1, s2, result;
    
    	cout << "String1: ";
    	cin >> s1;
    
    	cout << "String2: ";
    	cin >> s2;
    
    	result = s1 + " " + s2;
    	cout << "\n\n\n" << result << endl;
    
    	return 0x0;
    }
    

    Merkregel: Wenn du C machst, mach es so wie du angefangen hast. Wenn du C++ machst, nimmst du für sowas std::string, wie du oben siehst viel einfacher, klarer, schneller geschrieben, schöner, typsicher, sicherer......



  • Skym0sh0 schrieb:

    #include <iostream>
    #include <string>
    using namespace std;
    
    int main()
    {
    	std::string s1, s2, result;
    
    	cout << "String1: ";
    	cin >> s1;
    
    	cout << "String2: ";
    	cin >> s2;
    
    	result = s1 + " " + s2;
    	cout << "\n\n\n" << result << endl;
    
    	return 0x0;
    }
    

    Merkregel: Wenn du C machst, mach es so wie du angefangen hast. Wenn du C++ machst, nimmst du für sowas std::string, wie du oben siehst viel einfacher, klarer, schneller geschrieben, schöner, typsicher, sicherer......

    Danke erstmal für die Mühe!
    Aber leider kenne ich string schon, möchte es aber lieber nochmal mit char lernen, da mir sonst das Buch nichts bringen würde, wenn ich Teile, die ich nicht verstehe, einfach durch was Leichteres löse.



  • die Funktionen strlen und strcat arbeiten mit nullterminierten Zeichenketten, d.h. hinter der eigentlichen Zeichenkette ist noch ein Nullzeichen '\0'

    mit "ergebnis [laenge] = 32;" überschreibst du dieses Nullzeichen, d.h. du mußt dann noch "ergebnis [laenge + 1] = '\0';" machen



  • dd++ schrieb:

    die Funktionen strlen und strcat arbeiten mit nullterminierten Zeichenketten, d.h. hinter der eigentlichen Zeichenkette ist noch ein Nullzeichen '\0'

    mit "ergebnis [laenge] = 32;" überschreibst du dieses Nullzeichen, d.h. du mußt dann noch "ergebnis [laenge + 1] = '\0';" machen

    Danke, es klappt jetzt!
    Allerdings verwirrt mich das etwas, da ich auch an \0 gedacht habe und zeitweise "ergebnis [laenge + 1] = 0;" drin hatte (Im Buch stand, dass \0 im ASCII-System den Wert 0 hat), was aber nicht funktioniert hatte.



  • Dein Code oben ist voller Fehler. Zum einen spuckt mir MSVC sau viele Warnungen (deprecated und so) an und zweitens stürzt das Programm am Ende ab.

    #include <iostream>
    #include <string>
    using namespace std;
    
    int main()
    {
    	char ergebnis[42], eingabe [20];
    	int laenge;
    
    	cout << "Wort eingeben\n";
    	cin.getline(eingabe, 20);
    
    	laenge = strlen(eingabe);
    
    	strcpy(ergebnis, eingabe); // eingabe wird in ergebnis gespeichert
    	ergebnis[laenge] = ' ';
    
    	cout << "\n2. Wort eingeben\n";
    	cin.getline(eingabe, 20);
    
    	strcpy(ergebnis+laenge+1, eingabe); // Zeichenketten werden zusammengefügt in ergebnis
    
    	cout << "\n" << ergebnis << "\n";
    
    	system ("PAUSE");
    	return 0x0;
    }
    


  • Du hättest auch strcat mit " " machen können. (Achte auf die doppelten Anführungszeichen)
    Das Zeichen mit dem Wert 0 ist '\0'. (Achte auf die einfachen Anführungszeichen)



  • Skym0sh0 schrieb:

    Dein Code oben ist voller Fehler. Zum einen spuckt mir MSVC sau viele Warnungen (deprecated und so) an und zweitens stürzt das Programm am Ende ab.

    #include <iostream>
    #include <string>
    using namespace std;
    
    int main()
    {
    	char ergebnis[42], eingabe [20];
    	int laenge;
    
    	cout << "Wort eingeben\n";
    	cin.getline(eingabe, 20);
    
    	laenge = strlen(eingabe);
    
    	strcpy(ergebnis, eingabe); // eingabe wird in ergebnis gespeichert
    	ergebnis[laenge] = ' ';
    
    	cout << "\n2. Wort eingeben\n";
    	cin.getline(eingabe, 20);
    	
    	strcpy(ergebnis+laenge+1, eingabe); // Zeichenketten werden zusammengefügt in ergebnis
    	
    	cout << "\n" << ergebnis << "\n";
    	
    	system ("PAUSE");
    	return 0x0;
    }
    

    Hm, wo liegen denn die Fehler? Bei mir funktioniert das Programm und stürzt auch nicht ab.

    char ergebnis[20], eingabe [20];
    	int laenge;
    	cout << "Wort eingeben\n";
    	cin >> eingabe;
    	strcpy(ergebnis, eingabe);  // eingabe wird in ergebnis gespeichert
    	cout << "\n2. Wort eingeben\n";
    	cin >> eingabe;
    	laenge = strlen(ergebnis); // Länge von ergebnis wird ermittelt
    	ergebnis [laenge] = 32;
    	ergebnis [laenge + 1] = '\0';
    	strcat (ergebnis, eingabe); // Zeichenketten werden zusammengefügt in ergebnis 
    	cout << "\n" << ergebnis << "\n";
    	system ("\nPAUSE");
    


  • Jain, laufen tuts bei mir auch. Aber gib mal lange Strings ein, dann crasht es. Es wird dir vielleicht nicht angezeigt, aber es crasht.

    Die C Funktionen sind bei falscher Anwendung total unsicher, und leider sind sie sehr einfach falsch zu benutzen.

    Und wie zwischendurch mal gesagt wurde: Du überschreibst (in deinem ersten geposteten Programm das Nullterminierungszeichen mit "ergebnis[laenge] = ' ';", die Funktion sehen so nicht wann dein String zu Ende ist und warten auf das nächste Nullbit, alles dazwischen wird mit ausgegeben und verarbeitet -> böse



  • Skym0sh0 schrieb:

    Jain, laufen tuts bei mir auch. Aber gib mal lange Strings ein, dann crasht es. Es wird dir vielleicht nicht angezeigt, aber es crasht.

    Die C Funktionen sind bei falscher Anwendung total unsicher, und leider sind sie sehr einfach falsch zu benutzen.

    Und wie zwischendurch mal gesagt wurde: Du überschreibst (in deinem ersten geposteten Programm das Nullterminierungszeichen mit "ergebnis[laenge] = ' ';", die Funktion sehen so nicht wann dein String zu Ende ist und warten auf das nächste Nullbit, alles dazwischen wird mit ausgegeben und verarbeitet -> böse

    Das mit der \0 werde ich mir auf jeden Fall merken, ich bedanke mich bei allen die geholfen haben.



  • ...



  • Skym0sh0 schrieb:

    return 0x0;
    }
    

    Sein 0x0 ist natürlich nur ein Joke.
    Nicht angewöhnen.



  • volkard schrieb:

    Skym0sh0 schrieb:

    return 0x0;
    }
    

    Sein 0x0 ist natürlich nur ein Joke.
    Nicht angewöhnen.

    Ach, glaubst du?

    Und angewöhnen?
    -> Nenn mir einen Nachteil oder Unterschied gegenüber return 0;



  • Skym0sh0 schrieb:

    Die C Funktionen sind bei falscher Anwendung total unsicher, und leider sind sie sehr einfach falsch zu benutzen.

    Wenn man weiß was man tut sind die nicht unsicher.
    Allerdings sind, gerade für Anfänger die STL String natürlich besser, wenn man die Strings nur benutzen will. Da der TE aber offensichtlich auch die Hintergründe verstehen will, finde ich es gut, dass er sich damit beschäftigt.

    PS: Sobald es die WINAPI in C++ gibt, verzichte ich auch drauf, aber versuch mal einen STL String in RECV oder SEND zum Einsatz zu bringen ^^

    Insofern @TE: Daumen hoch 😉



  • volkard schrieb:

    Skym0sh0 schrieb:

    return 0x0;
    }
    

    Sein 0x0 ist natürlich nur ein Joke.
    Nicht angewöhnen.

    Also ich nehme bei sowas, wo es nicht unbedingt auf eine hexadezimale Darstellung ankommt, immer Dezimal-Ints, aber das ist sicherlich Geschmackssache.



  • It0101 schrieb:

    Skym0sh0 schrieb:

    Die C Funktionen sind bei falscher Anwendung total unsicher, und leider sind sie sehr einfach falsch zu benutzen.

    Wenn man weiß was man tut sind die nicht unsicher.

    Klar, wenn man weiss was man tut, ists es in Ordnung.

    It0101 schrieb:

    PS: Sobald es die WINAPI in C++ gibt, verzichte ich auch drauf, aber versuch mal einen STL String in RECV oder SEND zum Einsatz zu bringen ^^

    Naja, dann muss man was tricksen und sich was passendes schreiben, aber das ist nicht unmöglich. (Wenn man weiss, was man macht.)



  • Skym0sh0 schrieb:

    volkard schrieb:

    Skym0sh0 schrieb:

    return 0x0;
    }
    

    Sein 0x0 ist natürlich nur ein Joke.
    Nicht angewöhnen.

    Ach, glaubst du?

    Und angewöhnen?
    -> Nenn mir einen Nachteil oder Unterschied gegenüber return 0;

    Du tust mit dem Code so, als hätte es eine teifere Bewandtnis, als hätten die Einzelbits eine spezielle Bedeutung. Und jeder Leser stockt da erstmal und überlegt.

    Sollten sich Mathematiker ein

    return 113/355;
    

    angewöhnen? Sicherlich ist dieser Beinahe-Kehrwert von PI besonders hübsch und hat es aus mancherlei Gründen verdient, jedes Programm zu zieren. 🤡

    Ach, weil es so schön dazupasst. Vor ein paar Jahren kursierte hier der

    virtual void bar()=0x0;//gcc-shocker
    

    , der Auto war auch völlig sicher, daß man die 0 in Hex schreiben muss.



  • volkard schrieb:

    Du tust mit dem Code so, als hätte es eine teifere Bewandtnis, als hätten die Einzelbits eine spezielle Bedeutung. Und jeder Leser stockt da erstmal und überlegt.

    Ok, 1:0 für dich 😞
    Ich machs eigentlich nur rein fürs Aussehen, hab meine IDE auch so eingestellt, dass Zahlenliterale pink sind 😉



  • Vieles ist eben wirklich Geschmackssache, aber an manchen Stellen sind gerade Hexadezimalzahlen unnütz wie ein Kropf.
    Manche Sachen verursachen einfach unnötige Denkprozesse im Gehirn, aber solche Dinge macht auch Volkard, auch wenn er es nie zugeben würde 😉

    Es gibt nunmal nicht genau DIE richtige Programmierung, auch wenn das viele hier nicht wahrhaben wollen und sich aufführen für religiöse Fanatiker.


Anmelden zum Antworten