scanf kickt mich aus dem Programm raus...
-
Hallo Looooite!
Ich habe einen Code in C++ geschrieben, der mir eigentlich ein CD-Laufwerk öffnen soll:
int main() { string drive = "Z"; printf("What's the letter of your CD-Drive?\n"); scanf ("%s", &drive); printf("Drive opening now..."); OpenCloseDoor(drive, true); printf("Press any key to close the CD-Drive"); getch(); OpenCloseDoor(drive, false); return 0; }Das Problem ist, dass wenn ich beim scanf Befehl ankomme, hört das Programm auf zu laufen (Direkt nach der Eingabe!)

Wenn ich den scanf Befehl ausklammere läuft jedoch alles richtig!
Ich wäre froh, wenn mir jemand von euch helfen könnte

Danke im Voraus
Lg RogonPS: Hier noch der vollständige Code:
#include "wtypes.h" #include "winioctl.h" #include <stdio.h> #include <stdlib.h> #include <string> #include <time.h> #include <conio.h> using namespace std; // DriveName specifies the cd drive name (as string, eg: "D") // Open specifies whether to open or close drive bool OpenCloseDoor(const string& DriveName, const bool Open) { // Make drive name in the format "\\.\D:" where D is the cd drive const string Drive = string("\\\\.\\") + DriveName + string(":"); // Treat cd drive as an IO device file HANDLE hDrive = INVALID_HANDLE_VALUE; hDrive = CreateFile(Drive.c_str(), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); // Open or close as needed BOOL bRetVal = FALSE; if ((hDrive != INVALID_HANDLE_VALUE) && (NO_ERROR == GetLastError())) { DWORD dwDummy = 0; if (Open) { bRetVal = DeviceIoControl(hDrive, IOCTL_STORAGE_EJECT_MEDIA, NULL, 0, NULL, 0, &dwDummy, NULL); } else { bRetVal = DeviceIoControl(hDrive, IOCTL_STORAGE_LOAD_MEDIA, NULL, 0, NULL, 0, &dwDummy, NULL); } } return (!!bRetVal); // To avoid performance warning } int main() { string drive = "Z"; printf("What's the letter of your CD-Drive?\n"); scanf ("%s", &drive); system ("cls"); printf("Drive opening now..."); Sleep(2000); OpenCloseDoor(drive, true); system("cls"); Sleep(1000); printf("Press any key to close the CD-Drive"); getch(); OpenCloseDoor(drive, false); return 0; }
-
string drive = "Z"; scanf ("%s", &drive);Ist das ernst gemeint?
Nimm
std::cin >> drive;und misch in Zukunft nicht C und C++ so, als handele es sich um die selbe Sprache. Scanf kann mit komplexen Datentypen schlicht nicht umgehen.
-
@seldon:
Hallo Seldon!
Danke für die schnelle Antwort!
Eigentlich dachte ich, dass C beim C++ abwärtskompatibel ist!
Also wenn ich std::cin >> drive; statt scanf ("%s", &drive); eingebe gibt er mir folgenden Fehler:
error: 'cin' is not a member of 'std'
Hast du eine idee?
Lg Rogon

-
C kann zu C++ schon deshalb nicht abwärtskompatibel sein, weil C älter ist als C++. Es sind stumpf zwei verschiedene Sprachen, und es ist fatal, die eine wie die andere behandeln zu wollen oder sie ohne viel Vorsicht zu vermischen. Guter C++-Code und guter C-Code haben wenig miteinander gemein.
Was den Compilerfehler angeht, std::cout und std::cin befinden sich im Header <iostream>, also wird
#include <iostream>das Problem lösen. Das steht allerdings in jedem C++-Buch auf den ersten Seiten, also wundert es mich, dass du das nicht weißt - mit einiger Wahrscheinlichkeit solltest du deine Lernmethoden überdenken.
-
#include <iostream>
using namespace std; // So ersparst du dir immer std:: zu schreiben
// aber nicht in Klassen verwenden möglichst Lokal
// halten.int main()
{
cout<<"hallo";
return 0;
}
-
Wow, danke! Es funktioniert!

Ich kannte den std Befehl vorher noch nicht, aber ich danke dir auf jeden fall sehr, dass du mir in so weniger Zeit helfen konntest!
Das ist super!
Liebe Grüsse
Rogon
-
schrieb:using namespace std; // So ersparst du dir immer std:: zu schreiben
// aber nicht in Klassen verwenden möglichst Lokal
// halten.Neh, gar nicht verwenden. Wenn überhaupt, dann einzelne Bezeichnernamen importieren. Wann kapieren die Leute endlich das der Sinn von Namensräumen nicht der ist, sie wieder komplett auszuschütten?
@TE: Lern Grundlagen (darunter fallen auch Namensräume
), denn dass du so etwas triviales wie std::cout nicht kennst, ist sehr merkwürdig.. hol dir ein gutes Buch 
-
Den kanntest du nicht, weil du C lernst. Die Zeile mit dem string war bisher die einzige C++-Zeile in deinem Programm. Wie schon gesagt, steht das mit std:: und cin/cout, auf der ersten Seite in jedem C++-Buch. Du solltest wohl eher lernen, wie man in C mit Zeichenketten umgeht, das geht nämlich ganz anders.
Neh, gar nicht verwenden. Wenn überhaupt, dann einzelne Bezeichnernamen importieren. Wann kapieren die Leute endlich das der Sinn von Namensräumen nicht der ist, sie wieder komplett auszuschütten?
Ich zweifle deine Interpretation von Namensräumen an. Es ist nichts schlechtes daran, für sich selber einen Namensraum irgendwo komplett auszuschütten.
-
using-Direktiven sind manchmal sogar nötig, um ADL zu triggern.
-
SeppJ schrieb:
Es ist nichts schlechtes daran, für sich selber einen Namensraum irgendwo komplett auszuschütten.
Ja, aber Anfängern wird oft vermittelt: Scheiß auf std::, schütte es einfach in jedem Projekt in der main() und in allen Headern aus - und mehr wird nicht gesagt. Das ist sehr schade. Ich finde, man sollte
using namespace ...;wie dynamische Speicherallokierung durchnew&deleteerst als Zusatz lernen, und nicht als Selbstverständlichkeit.
-
Hoppla, jetzt verstehe ich gar nichts mehr!

Ich habe mir den Code aus verschiedenen Codes im Internet zusammengestellt und weiss eigentlich nicht genau was alle Befehle bedeuten!
Das using namespace scheint ja wichtig zu sein
könnte es mir bitte jemand kurz erklären?Und was ist denn std::cin >> drive;?
Ich kenne eben nur die C Programmierung und bin kein Profi!Lg
Rogon
-
rogon schrieb:
Ich habe mir den Code aus verschiedenen Codes im Internet zusammengestellt und weiss eigentlich nicht genau was alle Befehle bedeuten!
O.O
Hast du sie noch alle!? So lernt man doch kein C++? Hol dir schnell ein gutes Buch! Viel, das im Internet steht ist schrott.
C und C++ sind an sich völlig verschiedene Sprachen mit gleicher Syntax. Das verwirrt manchmal.
-
Hast du sie noch alle!? So lernt man doch kein C++?
Naja, ich kenne das C++ ja fast nicht!
Ich habe bisher nur das C gelernt
Was empfiehlst du mir beim C++ für ein gutes Buch?
Und was sind denn das jetzt für Befehle?
-
rogon schrieb:
Was empfiehlst du mir beim C++ für ein gutes Buch?
Es gibt sehr viele.
Extra dafür gibt es hier im Forum einen sog. Buchthread mit vielen guten Beiträgen zum Thema C++-Buch.Edit: Hier im FAQ (wo du auch öfter reinschauen solltest
).
-
Was willst du denn jetzt überhaupt? C oder C++? Wie schon gesagt, hast du bisher C gelernt, aber durch dein
Ich habe mir den Code aus verschiedenen Codes im Internet zusammengestellt und weiss eigentlich nicht genau was alle Befehle bedeuten!
hast du versehentlich C++ eingebaut, was natürlich schief ging. Aber da du dein C anscheinend mit einem C++-Compiler übersetzt hast, war es zumindest grammatikalisch richtig, weswegen dieser sich nicht beschwert hat. Was natürlich auch schlecht ist, das sollte man nie machen.
C und C++ sind wirklich sehr verschieden, sie haben bloß eine ähnliche Grammatik und manche Wörter sind gleich. Ungefähr so, wie wenn normale Leute mit Juristen reden. Man merkt zwar, dass die Sprache irgendwie ähnlich ist, aber man versteht nix und am Ende ist man sein Geld los.
Wenn du jetzt anfängst, auf C++ umzusteigen, dann darfst/solltest du alles vergessen, was du bisher gelernt hast.
-
314159265358979 schrieb:
using-Direktiven sind manchmal sogar nötig, um ADL zu triggern.
Bitte was?! Kannst Du bitte erklären, was Du mit diesem Satz meinst? So klingt das erstmal für mich nach einer falschen Aussage. Aber vielleicht missverstehe ich Dich ja auch ...
-
template <typename T> void foo(T& a, T& b) { std::swap(a, b); // kein ADL } template <typename T> void bar(T& a, T& b) { using std::swap; swap(a, b); // ADL }
-
rogon schrieb:
Eigentlich dachte ich, dass C beim C++ abwärtskompatibel ist!
[...]
std::string drive;
std::cin >> drive;
[...]
std::string drive;
scanf ("%s", &drive);Im Wesentlichen fliegt Dir das hier um die Ohren, weil Du lügst. Wegen "%s" erwartet scanf eine Adresse vom Typ char* und nicht string*. Die Sprache an sich lässt so etwas zu, weil die Sache mit den variadischen Funktionen in C überhaupt nicht typsicher ist.
Guck mal, ob Du bei Deinem Compiler so konfiguriert bekommst, dass er solche Sachen prüft und vor Missbrauch warnt. Die Funktionssignatur gibt zwar nicht genug Informationen her, um so etwas überprüfen zu können, aber da solche Fehler in C relativ prominent sind, hat der eine oder andere Compiler-Hersteller den Compilern den Zusammenhang zwischen dem Format-String und den folgenden Argumenten beigebracht.
Alternativ: Lass die Finger von Sachen, die nicht typsicher sind.
314159265358979 schrieb:
template <typename T> void foo(T& a, T& b) { std::swap(a, b); // kein ADL } template <typename T> void bar(T& a, T& b) { using std::swap; swap(a, b); // ADL }Erstens ist das das keine using-Direktive sondern eine using-Deklaration.
Zweitens triggerst Du hier nicht ADL per using-Deklaration sondern dadurch, dass das zweite swap unqualifiziert ist. Verbuchen wir das als ein Missverständnis.
-
krümelkacker schrieb:
Erstens ist das das keine using-Direktive sondern eine using-Deklaration.
Ist dem so? Was ist dann eine Direktive?
krümelkacker schrieb:
Zweitens triggerst Du hier nicht ADL per using-Deklaration sondern dadurch, dass das zweite swap unqualifiziert ist. Verbuchen wir das als ein Missverständnis.
Strenggenommen ja. Aber ohne using würde die unqualifizierte Version nicht funktionieren...
-
Direktiven erkennst du am Schlüsselwort
namespace. Also...using namespace dings;ist eine using-Direktive.
using std::swap;ist eine using-Deklaration.Ersteres sorgt dafür, dass, falls die Namenssuche im globalen Scope angelangt ist, auch Namen aus dings berücksichtigt werden.
Zweiteres führt den Namen einer Entität (Klasse, Funktion, etc, nur kein Namensraum) in den Scope ein, wo die using-Deklaration steht (typischerweise nicht der globale).