Du verwendest einen veralteten Browser. Es ist möglich, dass diese oder andere Websites nicht korrekt angezeigt werden. Du solltest ein Upgrade durchführen oder einen alternativen Browser verwenden.
C++Visual Studio verarscht mich, programmier anfänger
lerne gerade mit den Buch C++ Grundkurs, die Sprache C++ und habe mich für die Entwicklungsumgebung Visual Studio Community entschieden. Nun zum Problem:
Jedesmal wenn ich mit den Befehl cout oder printf in C arbeite , schließt sich das Ausgabe fenster sofort wenige Sekunden später.
Beispiel:
#include <iostream>
using namespace std;
int main() {
cout << "I like programming\n";
cout << "Ein Monster mit "
<< "zwei Zeilen\n";
return 0;
}
Gibt es dazu eine lösung oder muss ich mir eine andere Entwicklungsumgebung suchen?
Umm, ja. Das ist doch genau das, was das Programm machen soll. Etwas ausgeben und dann sich selbst beenden.
Was Du meinst ist wahrscheinlich daß das "Programmfenster" bzw. die "Konsole" nach dem Ende des Programms nicht auch geschlossen wird. Dazu wurde eine "eingebaute" Lösung schon genannt (Strg F5). Eine weitere Lösung wäre, den Cursor auf das letzte "return 0;" zu setzen und "Strg F10" zu drücken. Eine noch andere Lösung ware die Platzierung eines "Breakpoints" in der letzten Zeile (durch Mausklick links neben den Quelltext bei "return 0;").
Wenn du programmieren lernen willst: Lern googlen
Ich hab nur die Wörter C++ und denwichtigen Teil von deinem Satz kopiert "schließt sich das Ausgabe fenster sofort wenige Sekunden später."
Abgesehn von diesem Forumsbeitrag erklären schon die ersten zwei Treffer sofort eine Lösung...
Der Tipp mit dem Googlen ist übrigens ernster gemeint und wichtiger als man denkt: Um Programmieren zu lernen wirst du pausenlos Antworten brauchen. Dafür muss man in der Lage sein, sein Problem zu identifizieren und auf den Punkt zu bringen (hast du ja schon geschafft: Konsole schließt..)
Auch erfahrene Programmierer brauchen das ständig.
Später bei der Fehlersuche ist es das selbe: Was GENAU funktioniert nicht und wann funktioniert es nicht? Und wann funktioniert es? Meist liegt die Lösung auf der Hand, wenn man sich das exakt klar macht.
Kleine Ergänzung neben dem was schon gesagt wurde: du solltest dir klarmachen, dass cout kein Befehl ist und auch keineswegs das C++ Pendant zur C-Funktion printf. Der C-Code
Code:
printf("Hallo Welt");
ist eigentlich nur eine andere Schreibweise für
Code:
fprintf(stdout, "Hallo Welt");
Dieser Code beschreibt die Anweisung "Schreibe den String 'Hallo Welt' in den Ausgabestrom 'stdout'". Der entsprechende C++ Code sieht nun so aus:
Code:
cout << "Hallo Welt";
Nur dass stdout hier nicht stdout heißt, sondern cout. cout ist also der Name des Ausgabestroms, in den hinein ausgegeben werden soll, nicht die Funktion, die die Ausgabe ausführt. Die "Funktion", die - wie printf/fprintf in C - die Ausgabe ausführt, ist der Ausgabeoperator <<.
Die Entsprechung zu printf/fprintf ist also nicht cout, sondern der Ausgabeoperator <<. cout ist hingegen die Entsprechung zu stdout.
Heißt also: Gib endline auf "ghjk" aus? Und gib "ghjk" auf "asdf" aus?
stdio und iostreams sind vollkommen unterschiedliche Konzepte und es gibt keine naheliegende Entsprechung des Einen beim Anderen. Deshalb sollte man auch nicht versuchen, so eine Hirnakrobatik zu veranstalten.
Nur dass stdout hier nicht stdout heißt, sondern cout. cout ist also der Name des Ausgabestroms, in den hinein ausgegeben werden soll, nicht die Funktion, die die Ausgabe ausführt. Die "Funktion", die - wie printf/fprintf in C - die Ausgabe ausführt, ist der Ausgabeoperator <<.
Naja, cout steht für "character output" und ist letztlich ein Funktionszeiger bzw. ein Funktionsobjekt, welches das libc-stdout kapselt und auch zeilenweise synchronisiert. cout << ... ist also "syntaktischer Zucker" für den Funktionsaufruf: cout.operator<<(...);
während cout selber sowas wäre wie: cout.operator void *().
Die Entsprechung zu printf/fprintf ist also nicht cout, sondern der Ausgabeoperator <<. cout ist hingegen die Entsprechung zu stdout.
Das passt schon. Der <<-operator gibt ja jedes mal wieder ne Referenz auf den Ausgabestream (hier std::cout) zurück, die dann vom nächsten Aufruf als erstes funktionsargument genutzt wird. Genauso wie bei 5*2+3 auch nicht 3 zu 2 hinzuaddiert wird, sondern eben zum Ergebnis von 5*2.
asdfman schrieb:
stdio und iostreams sind vollkommen unterschiedliche Konzepte und es gibt keine naheliegende Entsprechung des Einen beim Anderen. Deshalb sollte man auch nicht versuchen, so eine Hirnakrobatik zu veranstalten.
Würd garnicht mal sagen, dass die sich so sehr unterscheiden. Aber prinzipiell stimme ich dir zu. Auch wenns gut gemeint ist verwirrt man Anfänger mit solchen halbgaren vergleichen eher.
Ergänzung ()
blöderidiot schrieb:
Naja, cout steht für "character output" und ist letztlich ein Funktionszeiger bzw. ein Funktionsobjekt [...]
holla, jetzt wirds aber ganz abenteuerlich. std::cout ist ein ganz normales globales std:: ostream Objekt und je nach dem, was rechts vom << steht ist das entweder eine Memberfunktion oder eben eine freie Funktion, die eine Referenz auf ein std:: ostream Objekt als ersten Parameter übergeben bekommt.
Ich glaube, du vermischt da cout mit Dingen wie z.B. std::endl. Das ist tatsächlich eine (template) Funktion (allerdings kein Funktionsobjekt).
Aber nochmal, das sind Dinge, mit denen sich Anfänger wirklich nicht beschäftigen sollten.
Nein. @Raidbey falls du das hier irgendwann mal lesen solltest und schon etwas mehr von Funktionen, Datentypen etc. verstehst:
<< ist linksassoziativ, d.h. da steht effektiv:
Code:
(((cout) << "asdf") << "ghjk") << endl;
Oder, wenn man das weiter zerpflückt:
Code:
ostream& a = cout;
ostream& b = a << "asdf"; // b = cout
ostream& c = b << "ghjk"; // c = cout
ostream& d = c << endl; // d = cout
<< ist zwar ein Operator, aber Operatoren sind an sich nichts anderes als ganz normale Funktionen mit einem oder zwei Parametern und einer Rückgabe. Sieht ungefähr so aus:
Genau diese Kompliziertheit bei schon relativ trivialen Dingen wie "etwas auf den Bildschirm bringen" (und wir jeden hier von Konsole und nicht mal irgendwas GUI-mäßiges) macht C++ schon irgendwie frustrierend.
Eigentlich kann man heutzutage von C++ nur abraten, wenn man es nicht unbedingt braucht.
Wobei "unbedingt braucht" in den allermeisten Fällen bedeutet, das man irgendwie vorhandenen C++-Quelltext weiter pflegen will/muss (der worst-case, weil man sich mit Code herumschlagen muss, den ein anderer geschrieben hat und der C++ im Zweifel auch nicht gut beherrscht), es für die Zielplattform nix Besseres gibt oder man Systemprogrammierung betreiben möchte.
Insofern sollte sich der Threadersteller auch noch mal Gedanken machen, ob er das sich wirklich antun möchte. Natürlich sofern er es freiwillig lernt.
@andy_m4:
Kann man zwar sicher nicht abstreiten, aber ganz unkommentiert möchte ich die Aussage da jetzt auch nicht stehen lassen.
Der Witz ist, dass c++ nur so kompliziert ist, wenn man es sich kompliziert macht. Eigentlich muss man sich mit diesem ganzen Implementierungsdetails erstmal garnicht abgeben, sofern man nicht anfängt eigene Bibliotheken zu schreiben (was zugegebenermaßen ein wichtiges Einsatzgebiert von c++ ist). In Java oder Python interessiert mich die Implementierung der Bibliotheksfunktionen ja auch erstmal nicht.
Nur mal ein anderes Beispiel zu nennen: Wie lange hast du std::vector genutzt ohne zu wissen, was genau templates sind und wie man selbst welche programmiert? Wie lange hat es danach gedauert, bist du festgestellt hast, dass meinen seinen eigenen Allocator verwenden kann?
C++ ist dank Smartphones und Cloud wohl wieder etwas im kommen, aber ja, wenn Produktivität und/oder Sicherheit wichtiger als Effizienz sind gibt es sicher andere Sprachen, die dafür besser geeignet sind (ich kenn keine andere gut genug um wirklich einen Vergleich anstellen zu können)
Ich finde ehrlich gesagt nicht, dass modernes C++ irgendwie unproduktiver wäre als z.B. C#. Letzten Endes hängt es von den zur Verfügung stehenden Libraries und Frameworks ab. Hast du für ein bestimmtes Thema eine gut dokumentierte, sauber in die Sprache eingebundene Library mit klar definierten Schnittstellen, kannst du die Geschichte genau so produktiv in C++ wie in C# lösen.
Der Witz ist, dass c++ nur so kompliziert ist, wenn man es sich kompliziert macht. Eigentlich muss man sich mit diesem ganzen Implementierungsdetails erstmal garnicht abgeben,
Verwirrend ist schon alleine, das es überhaupt so viele verschiedene Ausgabemöglichkeiten gibt.
Da gibt es eben einmal das klassische stdio-style printf. Aber auch das C++ bzw. iostream-Style cout.
Mir ist natürlich klar, warum das so ist und wo letztlich die Unterschiede liegen. Aber das sollte nichts sein, womit der Entwickler rumschlagen muss.
Und letztlich ja auch der Compiler. Aufgrund dieser historisch gewachsenen Strukturen sind ja C++-Compiler nicht gerade Roadrunner.
Und von solchen Geschichten wimmelt es ja an allen Ecken und Enden.
Nicht falsch verstehen. Natürlich hat C++ nach wie vor seine Berechtigung. Und natürlich kann man auch sozusagen "schönes" C++ schreiben (wenn man sich so anschaut, was man landläufig unter modernen C++ versteht), so das man mit Schmutzecken quasi kaum in Kontakt kommt.
Nach wie vor ist C++ aber eine sehr lernintensive Sprache und nach wie vor machen die Schmutzecken auch Probleme, weil eben leider Gottes nicht jeder so programmiert.
Miuwa schrieb:
C++ ist dank Smartphones und Cloud wohl wieder etwas im kommen,
Gerade in Bezug auf Effizienz wandert ja ohnehin immer mehr in den Compiler. Das ist sozusagen in Software gegossenes Know-How damit man sich eben nicht mehr darum kümmern muss selbst überall für Effizienz zu sorgen und damit sich sozusagen sein Quelltext zu beschmutzen.
Gruß
Andy
Ergänzung ()
antred schrieb:
Ich finde ehrlich gesagt nicht, dass modernes C++ irgendwie unproduktiver wäre als z.B. C#.
Naja. Ich persönlich würde jetzt an der Stelle auch nicht unbedingt den Vergleich zu C# ziehen wollen.
Aber mal ein ganz einfaches Beispiel. Ich brauch irgendwie nur mal ein kurzes Programm was mir irgendwas ausrechnet.
In C++ fang ich erstmal an irgendwie da ne Main-Funktion zu definieren und Variablen zu deklarieren wobei ich mir da auch noch um den Typ Gedanken machen muss.
In Lisp geht das deutlich angenehmer. Dort brauche ich Variablen nicht deklarieren. Ich kann also mir einfach ein Bezeichner her nehmen und den für Zahlen verwenden. Und diese Zahlen können auch beliebig groß werden. Das heißt ich muss auch keine Angst haben das wenn ich irgendwie über 64-Bit (oder was auch immer) komme, das es dann zu Überläufen kommt.
Ich benutze sie einfach und fertig.
Das Nette ist natürlich, ich kann trotzdem Variablen deklarieren. Und auch da muss ich mich nicht mit irgendeinen technischen Bereich abgeben. Für ne Variable ziffer kann ich halt sagen, die soll nur Werte von 0 bis 9 annehmen können. Und es wird auch wirklich sicher gestellt, das diese Variable niemals einen anderen Wert annehmen kann.
Jetzt würd der gemeine C++ Entwickler natürlich sagen: Jaja. Aber dafür brauchst Du u.U. ja auch Laufzeitchecks und die Kosten halt Zeit.
Stimmt. Aber wenn ich meine, das mein Programm ausreichend getestet ist und Geschwindigkeit tatsächlich ein Problem ist kann ich diese Checks entweder pro Variable oder pro Modul oder gar global ausschalten.
Auch das entwickeln ist sehr angenehm. Da Development-System, Compiling und das eigentliche Programm nicht wirklich getrennt sind, kann ich sozusagen am lebenden Programm arbeiten. Wenn ich irgendwas ändern möchte, dann mache ich das einfach, das Laufzeitsystem kompiliert die entsprechende Funktion neu und die Änderung ist sofort verfügbar.
Das selbe geschieht auch, wenn ein Error auftritt den ich z.B. nicht abgefangen hab. Dann hält das Programm an der Stelle an und ich kann halt meine Routine ergänzen und ohne Neustart das Programm dann an der Stelle fortführen.
Und das ist halt das, was ich unter Komfort bei der Programmentwicklung verstehe und was letztlich auch viel Zeit spart.
- Gib "asdf" auf den Ausgabestrom std::cout aus
- Gib "ghjk" auf den Ausgabestrom std::cout aus
- Mache ein endline auf dem Ausgabestrom std::cout
Für die ersten beiden dieser Anweisungen wäre der entsprechende C-Code:
Code:
fprintf(stdout, "asdf");
fprintf(stdout, "ghjk");
Lediglich das std::endl hat keine direkte Entsprechung in C.
asdfman schrieb:
stdio und iostreams sind vollkommen unterschiedliche Konzepte und es gibt keine naheliegende Entsprechung des Einen beim Anderen. Deshalb sollte man auch nicht versuchen, so eine Hirnakrobatik zu veranstalten.
Statt stdout/std::cout ist der Ausgabestrom hier pFile/file, ansonsten übernimmt auch hier der Ausgabeoperator << die Rolle von fprintf. Dass man die C++ Variante analog zu deinem Beispiel verschachteln kann zu:
Ich wollte eigentlich nicht mehr antworten, weil der Thread komplett entgleist ist, aber eigentlich heißt das ja nur, dass ich mit einer Antwort gar keinen Schaden mehr anrichten kann.
Ich habe VikingGe schon in einer PM dafür gedankt, dass er meinen Einwand, iostream erreiche das selbe Ziel (Daten in einen Stream zu schieben) auf völlig anderem Wege als stdio, so schön ausführlich erklärt hat.
Jetzt kommst du und machst das selbe nochmal und ihr beide leitet eure Beiträge damit ein, dass ihr mir widersprechen wollt. Da scheint dann also doch Erklärungsbedarf vorhanden zu sein.
Ich glaube, dadurch dass ich in meinem Beispiel nur String-Literals verwendet habe, kamen die elementaren Unterschiede der beiden Ansätze nicht deutlich genug zum Vorschein. Deshalb bastle ich hier mal ein Szenario, das man nicht trivial von stdio zu iostream umformulieren kann:
Code:
stdio: fprintf(stdout, "Vor %1$d Stunden war %2$s hier.\n", zeit, name);
iostream: std::cout << "Vor " << zeit << " Stunden war " << name << " hier." << std::endl;
Jetzt übersetzen wir unser Programm auf englisch:
Code:
stdio: fprintf(stdout, "%2$s was here %1$d hours ago.\n", zeit, name);
iostream: std::cout << name << " was here " << zeit << " hours ago." << std::endl;
Auf der einen Seite ändert man eine Stringkonstante, auf der anderen Seite muss man tatsächlichen Programmcode ändern.
Andersherum kann man in iostreams z.B. beliebige selbstgebastelte Transformationen einschieben (analog zu std::hex), was sich nicht einfach zu stdio übersetzen lässt.
Deshalb halte ich es -- gerade in Form eines Tips für einen Anfänger -- für falsch, diese beiden Features als unterschiedliche Ausdrucksweisen derselben Sache zu bezeichnen.
Ich wollte eigentlich nicht mehr antworten, weil der Thread komplett entgleist ist, aber eigentlich heißt das ja nur, dass ich mit einer Antwort gar keinen Schaden mehr anrichten kann.
Ich glaube, dadurch dass ich in meinem Beispiel nur String-Literals verwendet habe, kamen die elementaren Unterschiede der beiden Ansätze nicht deutlich genug zum Vorschein. Deshalb bastle ich hier mal ein Szenario, das man nicht trivial von stdio zu iostream umformulieren kann:
Code:
stdio: fprintf(stdout, "Vor %1$d Stunden war %2$s hier.\n", zeit, name);
iostream: std::cout << "Vor " << zeit << " Stunden war " << name << " hier." << std::endl;
Jetzt übersetzen wir unser Programm auf englisch:
Code:
stdio: fprintf(stdout, "%2$s was here %1$d hours ago.\n", zeit, name);
iostream: std::cout << name << " was here " << zeit << " hours ago." << std::endl;
Auf der einen Seite ändert man eine Stringkonstante, auf der anderen Seite muss man tatsächlichen Programmcode ändern.
Das liegt jetzt aber weniger in einem fundamentalen konzeptionellen Unterschied zwischen stdio und iostreams begründet, als vielmehr in unterschiedlichen Konzepten von C und C++ darüber, wie Zahlen in Strings eingefügt bzw. Teilstrings zu einem Gesamtstring zusammengefügt werden.
Dein erstes stdio-Beispiel könnte man auch umschreiben zu:
Dabei muss man zwar auf die C-Funktion sprintf zurückgreifen, das liegt aber nur daran, dass std::string, anders als die MFC-Klasse CString, bislang keine format-Methode anbietet, die einen Formatierungsstring mit einer variablen Parameterliste akzeptieren würde. Das ist aber eine Design-Entscheidung für die std:string-Klasse und hat nichts mit einem konzeptionellen Unterschied zwischen stdio und iostreams zu tun.
asdfman schrieb:
Andersherum kann man in iostreams z.B. beliebige selbstgebastelte Transformationen einschieben (analog zu std::hex), was sich nicht einfach zu stdio übersetzen lässt.
Wie schon im Zusammenhang mit std::endl erwähnt gibt es da tatsächlich gewisse Unterschiede, das mag wohl sein. Diese zeugen aber nicht von einem fundamental unterschiedlichen Konzept.
asdfman schrieb:
Deshalb halte ich es -- gerade in Form eines Tips für einen Anfänger -- für falsch, diese beiden Features als unterschiedliche Ausdrucksweisen derselben Sache zu bezeichnen.
Ich habe nichts davon geschrieben, dass es um unterschiedliche Ausdrucksweisen derselben Sache handeln würde. Ich habe geschrieben, dass zwischen beidem eine gewisse Analogie besteht, und dass im Rahmen dieser Analogie std::cout das Analogon zu stdout ist und der Ausgabeoperator das Analogon zu fprintf (und dessen Verwandten), und nicht etwa std::cout das Analogon zu printf.
Man kann sich natürlich auch wie du auf den Standpunkt stellen, dass stdio und iostreams vollkommen unterschiedliche Konzept seien, dann aber gilt erst recht die Aussage, dass std::cout kein Analogon zu printf ist. Kurz gefasst: man kann wie ich std::cout als Analogon zu stdout sehen und den Operator << als Analogon zu fprintf, oder man kann wie du jedwede Analogie bestreiten, aber in gar keinem Fall kann man std::cout als C++ Variante von printf ansehen.