Problem mit sprintf_s

  • C++

Es gibt 3 Antworten in diesem Thema. Der letzte Beitrag () ist von Renati.

    Problem mit sprintf_s

    Hi,

    ich bin Momentan dabei C++ zu lernen. Ich möchte mit der Funktion sprintf_s einen int in ein char-Array umwandeln. Dazu verwenden ich folgenden Code:

    Quellcode

    1. char buffer[100] = {0};
    2. sprintf_s(buffer, "%i", 42);
    3. MessageBox(hWnd, buffer, "Sinn des Lebens", NULL);


    Das Funktioniert auch noch soweit (die MessageBox verwende ich in diesem Beispiel nur zum überprüfen). Wenn ich allerdings versuche, diesen Code in eine extra Funktion zu kapseln, liefert mir die Funktion nur Zufallswerte. Hier mein Code:

    Quellcode

    1. //Die Funktion
    2. char* intToStr(int value)
    3. {
    4. char buffer[10] = {0};
    5. sprintf_s(buffer, "%i", value);
    6. return buffer;
    7. }
    8. //so wird die Funktion z. B. verwendet
    9. MessageBox(hWnd, intToStr(42), "Sinn des Lebens", NULL);


    Aber wie schon gesagt, es funktioniert nicht; es werden nur zufällige Werte ausgegeben.

    Weiß jemand woran das liegt bzw. wie ich den Code verbessern kann? Kann es sein, dass es daran liegt, dass ich mit dem "return buffer;" nur die Adresse des Buffers zurückliefere (die natürlich jedesmal anders ist)? Wenn ja, wie kann ich den Wert zurückliefern?

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „nikeee13“ ()

    So lange du Arrays und sprintf verwendest, lernst du kein C++, sondern allenfalls C. Falls du wirklich C++ lernen willst, vernichte sofort das Lernmaterial, das behauptet hat, es würde dir C++ beibringen. Damit kann es nur schlimmer werden. Jetzt zu deinem Problem:
    Du hast richtig erkannt, dass du hier nur eine Adresse zurück gibst. Leider endet dein Verständnis hier - und das ist schlecht, denn du hast gleiche mehrere katastrophale Fehler gemacht:
    1. Ein Array ist ein Zeiger und kennt seine Länge nicht. Mancher Compiler (der von Microsoft) mag das zurecht biegen können, das ist aber weder C noch C++, was du dann hast. Solltest du jemals einen anderen Compiler benutzen, wird dein Programm explodieren.
    2. Die Gültigkeit des Inhalts eines auf dem Stack allokierten Speicherbereichs (dein Array) ist spätestens mit dem Verlassen der Methode (oder Funktion) nicht mehr garantiert. Da du nur einen Zeiger zurück gibst, wird nur dieser im Rahmen der Copy-Semantik kopiert.

    Wirf deinen Code weg und lern' C++ vernünftig. Beschäftige dich insbesondere mit der Speicherverwaltung.

    Bonusüberlegung: Die wirklich interessante Frage ist eigentlich, warum die Adresse des Arrays auf dem Stack bei dir variiert. So natürlich, wie du denkst, ist das nämlich gar nicht. Doch das würde zu weit führen... (Tipp: Es hat mit der Prozessausführung zu tun - nicht mit der Speicherverwaltung von Windows, denn die ist virtuell!)

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Renati“ ()

    Danke für die ausführliche Antwort. Ich verwende im Moment leider noch kein richtiges Lernmaterial sondern nur Google bzw. MSDN zum Nachschauen der Funktionen.

    Ich denke ich habe das Problem soweit verstanden, allerdings ist mir noch nicht klar, wie ich das jetzt in Code umsetzen soll bzw. es gibt scheinbar bessere Möglichkeiten, da du ja sagst, mein Code wäre kein richtiger C++-Code.

    Ich werde morgen auch schauen, was ich zum Thema Speicherverwaltung finde.
    Im Gegensatz zu vielen anderen Sprachen ist Learning-by-doing bei C++ keine empfehlenswerte Methode. Ich würde auch kein Online-Tutorial benutzen, da einem hier selten ein ausreichendes Verständnis der C++ zu Grunde liegenden Konzepte vermittelt wird. Selbst bei Büchern muss man schauen, woran man gerät. Generell zu meiden sind Kombi-Bücher mit "C / C++" im Titel.
    Der geistige Vater von C++, Bjarne Stroustrup, hat selbst einige Bücher geschrieben und äußert sich auch in seinem FAQ zum Lernen der Sprache. Bei C++ würde ich mehr als bei jeder anderen Sprache mein Lernmaterial sorgfältig auswählen. Wichtig ist insbesondere eine gründliche Behandlung der Standardbibliothek.

    Darüber hinaus würde ich nicht direkt anfangen, meinen Horizont auf Microsofts kleines C++-Universum einzuschränken. Als Referenzen solltest du - außer natürlich für Systemaufrufe - nicht die MSDN, sondern zum Beispiel cplusplus.com/reference/ oder en.cppreference.com/w/cpp verwenden. Ich würde dir prinzipiell auch zu einem anderen Compiler wie zum Beispiel g++ bzw. MinGW raten, da der Microsoft-Compiler nicht gerade berühmt für seine Standardkonformität ist. Den kannst du später immer noch benutzen, wenn du C++/CLI oder unbedingt Visual Studio verwenden willst. Es ist besser, du lernst es erst richtig und passt dich dann an den Microsoft-Murks an, statt mit dem Microsoft-Compiler zu lernen und dann festzustellen, dass du mit allem anderen nicht klarkommst, weil das dem Standard folgt.

    Was deinen Code angeht:
    • C++ bietet eine String-Klasse an. Die kann man nutzen.
    • Irgendwas in einen String konvertieren macht man in C++ über Streams, hier zum Beispiel stringstream.
    • Der Rückgabewert von intToStr wird kopiert. Die Gründe findest du in einem Buch. ;)


    So könnte das aussehen:

    C-Quellcode

    1. #include <iostream>
    2. #include <sstream>
    3. #include <string>
    4. using namespace std;
    5. string intToStr(int value)
    6. {
    7. // Einen String-Stream instanzieren
    8. stringstream outputStream;
    9. // Integer mit Stream-Operator in Stream einlesen
    10. outputStream << value;
    11. // Den Stream repräsentierenden String zurück geben
    12. return outputStream.str();
    13. }
    14. int main()
    15. {
    16. // Integer umwandeln in string und ausgeben
    17. cout << intToStr(42) << endl;
    18. // Der Vollständigkeit halber: cout kann das auch selbst
    19. cout << 42<< endl;
    20. return 0;
    21. }

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Renati“ ()