Problem mit Zeichenkette
-
Bin ich zu blöd hier den Fehler zu sehen?
Hab gerade angefangen mir C++ autodidaktisch beizubringen...
Dabei arbeite ich ein Buch Schritt für Schritt durch.Momentan behandel ich das Thema "Ein- und Ausgabe von Zeichenketten"
Wo ich dieses Beispiel übernahm:#include <cstdio> #include <iostream> using namespace std; int main() { char* string; gets(string); puts(string); return 0; }Das Problem besteht darin, dass das Debugging eine Warnung ausgibt und das Ausführen die Fehlermeldung.
"Run-Time Check Failure #3 - The variable 'string' is being used without being initialized."
ausgibt.
Wo liegt das Problem dafür? Warum nimmt das Proggi die Variable nicht an?
Ich weiß, dass der Quelltext unzumutbar einfach ist... Entschuldigt^^Danke schonmal im Vorraus!
PS: Benutze "Visual C++ 2008 Express Edition"
-
Dieser Thread wurde von Moderator/in Unix-Tom aus dem Forum MFC (Visual C++) in das Forum C++ verschoben.
Im Zweifelsfall bitte auch folgende Hinweise beachten:
C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?Dieses Posting wurde automatisch erzeugt.
-
Wenn du schon C++ lernst, dann bitte richtig.
... std::string str; std::cin >> str; std::cout << str; ...Zum eigentlichen Problem: Du hast einen Zeiger erstellt, der aber auf keinen Speicher zeigt..
-
Ja ich versuchs ja...
das Problem konnte trotzdem nicht behoben werden.
Programm weist nun auf Fehler im Quelltext hin
danke trotzdem^^
-
Fragesteller1992 schrieb:
Ja ich versuchs ja...
das Problem konnte trotzdem nicht behoben werden.
Programm weist nun auf Fehler im Quelltext hin
danke trotzdem^^Aha. Dann ist ja Alles klar.
Gruß,
Simon2.
P.S.: Wenn Du Dich fragst, was dieser Post soll:
Hier können nur Fragen beantwortet werden, die man auch stellt - und "Das Programm" (vermutlich der Compiler) zeigt Dir bestimmt mehr als die Meldung "Fehler im Quelltext" an.
Falls Du sie nicht verstehst, könnten wir Dir bei ihrer Deutung helfen ... aber seltsamerweise nicht, ohne sie zu kennen.
-
Nein bescheuert bin ich auch nicht. Genauso wenig wie ihr.
Der Grund warum ich das Fehlerprotokoll nicht mit beschrieben oder gar kopiert habe ist, dass ich eigentlich dachte, ihr könntet mir den Fehler am bloßem Quelltext beschreiben. (Da theoretisch keiner kommen sollte, weil ich diesen haargenau aus dem Buch, "C/C++ Referenz" von Nootz-Morick, kopiert habe.
Im Grunde ist es nicht wichtig, da diese Variante mit "gets" und "puts", nur eine von Vielen ist, eine Zeichenfolge einzulesen und auszugeben.
Aber hier noch mal das Build-Protokoll aus dem Originalquelltext:
1>------ Neues Erstellen gestartet: Projekt: Test, Konfiguration: Debug Win32 ------ 1>Die Zwischen- und Ausgabedateien für das Projekt "Test" mit der Konfiguration "Debug|Win32" werden gelöscht. 1>Kompilieren... 1>Test2.cpp 1>c:\dokumente und einstellungen\...\visual studio 2008\projects\test\test\test2.cpp(8) : warning C4996: 'gets': This function or variable may be unsafe. Consider using gets_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. 1> c:\programme\microsoft visual studio 9.0\vc\include\stdio.h(279): Siehe Deklaration von 'gets' 1>c:\dokumente und einstellungen\qwertzus\eigene dateien\visual studio 2008\projects\test\test\test2.cpp(8) : warning C4700: [u][b]Die nicht initialisierte lokale Variable "string" wurde verwendet.[/b][/u] 1>Manifest in Ressourcen wird kompiliert... 1>Microsoft (R) Windows (R) Resource Compiler Version 6.1.6723.1 1>Copyright (C) Microsoft Corporation. All rights reserved. 1>Verknüpfen... [...] 1>Test - [u][b]0 Fehler, 3 Warnung(en)[/b][/u] ========== Alles neu erstellen: 1 erfolgreich, Fehler bei 0, 0 übersprungen ==========danke
-
Ich habe ja schon gesagt, was das Problem ist.
Kannst ja mal das Beispiel hier anschauen:
http://www.cplusplus.com/reference/clibrary/cstdio/gets.htmlNa. Etwas aufgefallen? Du hast lediglich einen Zeiger ohne Speicher. Beim anderen Beispiel wird ein char-Array angelegt, wo dann reingeschrieben wird.
-
Fragesteller1992 schrieb:
...
Genau genommen hast Du immer noch keine Frage gestellt.

Aber wollen wir den Korinthenkacker mal eingepackt lassen.
Was Du da siehst, sind Warnungen. Die sind compilerspezifisch und deswegen sind sie nicht so einfach am Quelltext vorherzusagen - dieser Compiler warnt vor diesem und jener vor jenem, ein dritter vor gar nichts, .... .
Hier sagt er einfach:Fragesteller1992 schrieb:
...
...gets': This function or variable may be unsafe. ...Die nicht initialisierte lokale Variable "string" wurde verwendet.(wieso er unten auf "3 warnings" kommt, weiß ich allerdings auch nicht)
Zur zweiten Warnung hat drakon bereits geschrieben: Da hast Du einen Fehler gemacht (stellst keinen Speicher bereit, in den gets() schreiben kann, sondern lässt ihn "irgendwohin" schreiben), den der Compiler aber nicht zuverlässig als solchen erkennen kann ... deshalb- "nur" eine warning und
- genau deshalb ist es immens wichtig, auch warnings zu beachten!!
Die erste weist Dich auf ein prinzipielles Problem mit gets() hin: Diese Funktion macht Dein Programm anfällig für einen "buffer overflow" - also selbst wenn Du Speicher bereitstellst, kann gets() nicht wissen, wieviel Platz er da hat.
Werden mehr Zeichen gefunden als Du Speicher bereitgestellt hast, wird (nach aller Erfahrung) in den Speicher "dahinter" geschrieben ... und damit kann alles Mögliche passieren.
Das ist übrigens eine bei Hackern sehr beliebte Schwäche von C-Programmen (und von C++-Programmen, die Texthandling mit char* machen).Dein Compiler schlägt Dir als Lösung die compilerspezifische Funktion "gets_s()" vor, die allerdings nur dieser MS-Compiler kennt - auf anderen Compilern klappt das nicht.
Hier im Forum wurde Dir als Lösung der Einsatz von std::string und std::stream (bzw. dessen "Kinder") vorgeschlagen, denn:Fragesteller1992 schrieb:
...Im Grunde ist es nicht wichtig, da diese Variante mit "gets" und "puts", nur eine von Vielen ist, eine Zeichenfolge einzulesen und auszugeben. ...
stimmt zwar, aber so ziemlich die unsicherste (in vielerlei Hinsicht) und umständlich.
Nimmt man std::string / std::stream, hat man es gleichzeitig sicher(er) UND einfacher als mit gets()/gets_s() (und im Gegensatz zu gets_s() noch portabel).Gruß,
Simon2.
-
Okay danke Leute!
Ja ne Frage wars nicht... Dummheit von mir.
Habs verstanden. Werde diese Variante mit char* in den Wind schlagen und stattdessen doch auf eure Varianten mit std::stream und std::string zurückgreifen.
Danke nochmal! War sehr hilfreich!
-
Fragesteller1992 schrieb:
Okay danke Leute!...
Danke für die gute Rückmeldung!

Gern geschehen.Gruß,
Simon2.
P.S.: Eine "Dummheit" war das IMHO nicht, sondern einfach eine Erfahrung, die jeder mal machen muss, der weiterkommen will. Ich selbst bin auch erst nach vielen char*-Fehlversuchen bei std::string gelandet - vorher weiß man diese Klasse (und den Rest der StdLib) oft gar nicht richtig zu schätzen.

-
Fragesteller1992 schrieb:
Danke nochmal! War sehr hilfreich!
Vielleicht noch einen Tip: Falls du wirklich C++ verwenden willst, greife niemals auf ein Buch zurück was sowohl C als auch C++ im Namen trägt ("C/C++ Referenz" ist nur ein Beispiel von vielen...). Es ist zwar auch mit C++ Büchern schwierig gute zu finden, aber bei den "C/C++" Bücher wird eigentlich ohne Ausnahme kein gutes C++ gezeigt (sondern nur C mit einen Hauch ++...).
cu André