was ist falsch an der syntax? ich kann keine eingabe machen, nach dem ich aufgefordert werde, die frage mit ja oder nein zu beantworten. do { printf("Gut gemacht"); printf("\n"); printf("\n Nochmal? (J/N)"); scanf("%c", &b); } while (b=='J' || b=='j'); (ich habe das beispiel ein bissel abgewandelt, damit es einfacher aussieht.)
bei mir läuft das beispiel einwandfrei. was für einen typ hat deine variable b. du solltest vor dem scanf noch den input buffer leeren, kann sonst zumindest bei dem beispiel probleme geben
@Tobi die variable b ist vom typ char (siehe scanf-funktion, c steht für char) wie kann ich denn den input puffer leeren?
das %c heisst ja nicht, dass es wirklich char ist.. :) fflush(stdin) normalerweise
@Tobi ich dachte, dass ist so vereinbart unter c. d=dezimal x=hex und c eben char. wo genau soll ich denn den fflush(stdin) einfügen? vor die do-schleife?
@ Rufus T. Firefly do { printf("Gut gemacht"); printf("\n"); printf("\n Nochmal? (J/N)"); b=gets(); //oder b=getc(); } while (b=='J' || b=='j');
@ Rufus T. Firefly Habe mit diesem Entleerungsbefehl noch nie gearbeitet. Sieht die Syntax dann so aus? do { printf("Gut gemacht"); printf("\n"); printf("\n Nochmal? (J/N)"); fflush(stdin); scanf("%c", &b); } while (b=='J' || b=='j');
Wenn, dann so. Besser, aber das habe ich in einem vorherigen Post bereits erwähnt: Kein scanf verwenden, sondern getc oder getch.
@Ulf: >>ich dachte, dass ist so vereinbart unter c. >>d=dezimal >>x=hex >>und c eben char. Die Funktionen printf, scanf & Co führen keinerlei Typprüfung durch. Du kannst einem printf("%d") statt einem int jeden beliebigen anderen Typ übergeben. Dann passiert natürlich meist nicht das erwartete, den Compiler schert es jedoch nicht, er übersetzt es ohne Warnung. Gruß, Michael
@ Rufus T. Firefly ich arbeite zur zeit mit dem c-compiler von keil. dieser kennt den befehl fflush(stdin); nicht. muss ich da noch ne header-datei einfügen, in der dieser befehl vereinbart ist? wenn ja, welche?
Such' selbst danach: findstr /s /c:"fflush" %include%\*.h (statt %include% nötigenfalls das include-Verzeichnis Deines Compilers angeben) Ansonsten: nicht ich habe Dir den fflush-Tip gegeben, also beschwer' Dich nicht bei mir. Ich wiederhol's nochmal: Nimm getc/getch!
@ Rufus T. Firefly ok danke. jetzt geht´s. wenn ich getc / getch benutze, sieht dann die schleife wie folgt? do { printf("Gut gemacht"); printf("\n"); printf("\n Nochmal? (J/N)"); b=getc(); //oder b=getch(); } while (b=='J' || b=='j');
@ Rufus T. Firefly erst mal kommt beim compilieren ne warnung. die kann man ja übergehen. beim ausführen stockt das programm dann aber. ich kann zwar 'j' eingeben, aber dann passiert nix. er hängt sich auf. irgendwie komisch... hast du noch nen tipp?
> erst mal kommt beim compilieren ne warnung. die kann man ja
übergehen.
Das machen viele. Und wundern sich.
Lass' Dein Programm doch mal im Debugger laufen.
"erst mal kommt beim compilieren ne warnung. die kann man ja übergehen." Wo steht denn das ? Eine Warnung ist in der Regel nicht nutzlos (bis auf Ausnahmen, z.B. beim AVR-GCC: suggest parentheses around && within || ). Man muß sie verstehen und dann erst weiß man ob man sie übergehen kann. Besser ist allerdings, den Quelltext so umzuschreiben, daß die Warnung entfällt. Peter
Hi @MSE >Die Funktionen printf, scanf & Co führen keinerlei Typprüfung durch. Du >kannst einem printf("%d") statt einem int jeden beliebigen anderen Typ >übergeben. Dann passiert natürlich meist nicht das erwartete, den >Compiler schert es jedoch nicht, er übersetzt es ohne Warnung. Der GCC bringt da durchaus eine Warnung. Matthias
"Der GCC bringt da durchaus eine Warnung." das liegt aber, wie hier vor kurzem schon einmal festgestellt wurde an einer speziellen erweiterung des gcc die nicht standard ist. normalerweise kann ein compiler nicht das format von diesen befehlen überprüfen @rufus die warnung besagt bei mir zumindest,dass getc zu wenig parameter hat.(normaler win gcc) allerdings bleibt das problem, dass das programm sofort nach egal welcher eingabe abbricht, da noch zeichen im eingabepuffer sind (mindestns das enter)
Hi und? Ist das jetzt negativ das der GCC einen vor evtl. Programmierfehlern warnt? Peter schreibt z.B. >Eine Warnung ist in der Regel nicht nutzlos (bis auf Ausnahmen, >z.B. beim AVR-GCC: suggest parentheses around && within || ). Warum soll denn diese Warnung nutzlos sein? && bindet stärker als ||. Das ist nicht unbedingt allgemein bekannt und kann schonmal zu Fehlern führen bzw. erleichtert eine Klammer um den Ausdruck beim überfliegen von fremdem Sourcecode die Lesbarkeit. Ich hab in den letzten Wochen in mehrere kLOC eingelesen. Da ist man um jede Erleichterung froh. Und diese Warnungen ermutigen den Programmierer lesbaren Code zu erzeugen. Matthias
"und? Ist das jetzt negativ das der GCC einen vor evtl. Programmierfehlern warnt?" nein, ganz sicher nicht. ich wollte damit nur sagen, dass man sich darauf nicht verlassen kann/soll. meistens sind compiler-warnung sehr sinnvoll und zur not kann man ja alles ausschalten :)
Na, Tobi, wenn die Warnung besagt, daß getc() zu wenige Parameter hat, dann solltest Du Dir mal die Dokumentation ansehen, die beschreibt, wie getc() zu verwenden ist - offensichtlich machst Du da was falsch. Das ist ja der Sinn von Warnungen ...
ich hab in der hilfe geschaut und weiss auch was da hinkommt. das war mehr ein hinweis an den threadstarter, der sich wegen einem fehler wunderte. ich suche immer erst selber, bevor ich andere frage
@Tobi: ISO/IEC 9899:1999 sagt: 7.19.5.2, Absatz 2: If stream points to an output stream or an update stream in which the most recent operation was not input, the fflush function causes any unwritten data for that stream to be delivered to the host environment to be written to the file; otherwise, the behavior is undefined. Kurz: fflush(stdin) kann alles mögliche veranlassen, man sollte sich also auf nichts verlassen, und schon gar nicht, daß es dieses Problem zuverlässig löst. Wenn es klappt, dann weil Dein Compiler und Deine libc es gut mit Dir meinen, kann morgen oder gar auf einer anderen Plattform schon ganz anders aussehen.
ok, werd ich mich mal bei meinem prof beschweren, haben wir dort gelernt. womit kann man denn iso kompatibel die daten in einem stream verwerfen?
Gar nicht :-( Du kannst es nur weglesen. Wenn Du z.B. weißt, daß als nächstes erwünschtes Zeichen eine Ziffer kommt, kannst Du solange mit fgetc lesen, bis isdigit() greift, die erste Ziffer mit fungetc wieder zurückschreiben, und dann mit scanf drangehen. fungetc ist iirc aber auch nur auf ein einziges Zeichen definiert. scanf habe ich übrigens wegen der zahlreichen Komplikationen, die einem ständig irgendwie in die Beine springen, bisher so weit gemieden wie möglich, und das mit Erfolg.
"Warum soll denn diese Warnung nutzlos sein? && bindet stärker als ||." Ich erwarte von einer Programmiersprache, daß sie streng logisch ist. Aber nur bei einer bestimmten Vorrangregel zu warnen ist doch völlig unlogisch. Wenn eine Warnung, dann aber gefälligst auch bei sämtlichen anderen kombinierten Ausdrücken: warning: suggest parentheses around * within + warning: suggest parentheses around % within - warning: suggest parentheses around + within & warning: suggest parentheses around | within && usw. usw. Entweder ich kenne die Vorrangregeln oder ich nehme Klammern. Peter
Hi die Erfahrung von vielen C-Programmierern zeigt eben das dieses Verhalten (und speziell dieses) bei if-Abfragen zu Fehlern führt. Matthias
@Matthias, aber dann wohl nur bei GCC-Programmierern :) Weder Borland noch Microsoft Visual C++ usw. kennen diese Warnung. Ich toleriers ja auch, daß manche Entwickler eben ihre persönliche Note reinbringen wollen, ist ja schließlich kostenlos. Aber sagen darf ich doch, daß ich persönlich solche Ungleichbehandlung unlogisch und überflüssig finde. Ich würde es bei einem kostenpflichtigen Compiler jedenfalls als Bug reklamieren. Peter
selbst vc++ liefert bei gewissen konstrukten warnungen mit der empfehlung, klammern zu setzen. ich weiss jetzt nicht mehr genau wann, möglicherweise bei ausdrücken welche shiftoperationen zusammen mit weiteren bitweisen operatoren enthalten. hab schon ewigs nicht mehr mit vc++ gearbeitet. auch hier ist der grund, dass viele programmierer die operatorpräzedenzen von c nicht soo genau kennen (wozu auch, dazu gibts schliesslich klammern:) bzw. hier eine häufige fehlerquelle liegt.
Hi
@peter
>aber dann wohl nur bei GCC-Programmierern :)
Na was meinst du warum M$-Software im allgemeinen mehr Bugs als kByte
Programmcode hat ;-)
Matthias
Ach, das ist der Grund warum die Programme immer unflätiger in der Größe werden, man will also die Bugs/Byte Ratio drücken! Und da die Herren wohl an der Variable Bugs nichts ändern können... :-)
Hi wie beginnt jedes M$-Programm? char make_programm_look_big[1000000*WINDOWS_VERSION]; Matthias
@peter dannegger: > Weder Borland noch Microsoft Visual C++ usw. kennen diese Warnung. [...] > Aber sagen darf ich doch, daß ich persönlich solche > Ungleichbehandlung unlogisch und überflüssig finde. Ich würde > es bei einem kostenpflichtigen Compiler jedenfalls als > Bug reklamieren. Oh, mann!!! Software-Qualität ist bei Dir wohl auch ein Bug, wie??? Mach' doch mal die Augen auf: Unmengen von Viren und Sicherheitsproblemen bei Windows-Plattform die zum Großteil auf simple Programmierfehler zurück zu führen sind. Buffer- und Integer-Overflows, switch-Statements mit fehlenden default-Label, unintialisierte Variablen, falsche if-Statements etc. Über 3/4 dieser Fehler kann ein Compiler entdecken! Und jetzt gibt's das auch alles kostenlos bei ganz normaler Elektronik, da überall Mikrocontroller drinn sind und diese Mikrocontroller mit kaputten Compilern programmiert werden oder der Peter den Compiler zurück gibt, wenn er ihn vor einem Fehler warnt. Und warum das nur? Na, weil der Borland-Compiler keine Warnung ausgibt, und der Peter dieses kaputte Verhaltener als "Standart" erhoben hat. Getreu nach dem Motto: Das kaputte Borland- und Microsoft-Verhalten gleich mal auf die Alltags-Elektronik übertragen. Man, man, man... Mach' mal Deine Augen auf und erweitere Deinen Horizont! Software-Qualität ist wichtiger denn je! Und dafür braucht es ordentliche Werkzeuge die den Programmierer ordentlich unterstützen. Wenn ein Programm schon in einer kaputten Programmiersprache wie z.B. 'C' oder 'C++' erstellt werden muss, dann muss der Compiler den Programmierer vor möglichst allen Problemen warnen und möglichst alle Fehler entdecken. Aber solange es noch "Hacker" (Programmierer sind das keine) gibt, die eine gerechtfertigte Warnung des Compilers als Bug klassifizieren, solange dürfen wir uns über abstürzende Fernseher und Waschmaschinen und Viren auf'm Handy erfreuen.
Vielleicht sollten auch Leute, die nicht programmieren können, keine Software für Mikrocontroller oder sonstwas schreiben, von dem wesentlich mehr abhängt als ein entgangener Highscore, weil die Heldenfigur durch den Boden gefallen ist, weil einer das Vorzeichen versaubeutelt hat. Es gibt selbstverständlich Sprachen, die es einem schwieriger machen Mist zu bauen, aber das ist keine Entschuldigung dafür, daß Leute Mist bauen, weil sie ihre Sprache nicht können. Allerdings finde ich es auch gut, wenn mich der Compiler bei Dingen die ihm suspekt erscheinen anbläst, aber wenn ich das nicht gezielt abstellen könnte, würde es mich auch ankotzen. Manchmal nutze ich sehr gerne -ansi -pedantic, dann ist es auch OK wenn er darauf besteht, daß eine Quelle in einem Newline endet. Meine Programme verlassen meinen Rechner auch nicht, wenn sie bei -Wall noch mucken. Aber wenn ich sowas wie while(*s) *p++ = *s++; meine, dann will ich nicht while(*s != NULL) { *(p++) = *(s++); } hinschreiben müssen. Gerade der Vergleich auf 0 ging mir bei den ersten Javaexperimenten tierisch auf den Keks. if (i) war eben nicht OK, es musste if (i != 0) sein... aber ich schweife ab.
Zotteljedi: auch Danke. @Michael (ein anderer), wer denkt, daß ein Compiler einem in den Kopf sehen kann, ob ein Konstrukt potentiell anders gemeint sein könnte, der ist aber sowas von auf dem Holzweg. Warnungen, die funktional völlig richtigen Kode anmeckern, wiegen Dich nur in einer Scheinsicherheit und verleiten zu weniger Sorgfalt. Das Risiko von Programmierfehlern erhöht sich dadurch also nur. Logische Fehler kann eh kein Kompiler entdecken. Der Kompiler ist kein Mensch, er kann also den Kode nicht verstehen. Peter
Peter: Danke. Du bist zwar in einigen Dingen anderer Ansicht als ich, aber ich gewinne den Eindruck, daß Du Dich schon etwas länger als ein, zwei Jahre mit der Materie beschäftigen dürftest ... Zum mich-in-träumerische-Sicherheit-wiegen nehme ich PC-Lint, um zu wissen, was passiert, einen Debugger.
@peter dannegger: Ich habe nie behauptet, dass ein Compiler logische Fehler entdecken kann. Was er jedoch wunderbar machen kann, ist den Execution-Path zu analysieren. Und auf diesem Weg kann ein Compiler eine große Menge Probleme entdecken. Wenn ISO-C99 definiert, wie bei scanf und printf die Argumente zum Format-String passen müssen, ist es für einen ISO-C99 Compiler überhaupt kein Problem, diese Information auch zu verwerten und zu analysieren. Nach der Argumentationsweise, Sicherheitsmasnahmen (Warnungen) wiegen die Benutzer (Programmierer) in falscher Sicherheit und würden zu Leichtsinn führen, kann man sämtliche Sicherheitsvorkehrung anzweifeln. Beispiel Auto: Danach wäre ein Fahrzeug mit Gurt, Airbag, ABS und aktivem Fahrwerk potentiell gefährlicher, als ein Auto ohne diese Einrichtungen. Richtig ist natürlich, dass es einen Prozentsatz von Autofahrern gibt, die sich tatsächlich in falscher Sicherheit wägen und aufgrund der Ausstattung ihrers Autos meinen, ihnen könne nichts passieren und deshalb sehr risikoreich fahren. Analog gibt es "Programmierer", die Code zusammen hacken, den durch den Compiler mit -Wall -pedantic -Werror schicken, und wenn der Code dann kompiliert, ihn als Fehlerfrei deklarieren. So funktioniert das natürlich nicht. Diese "Programmierer" werden ebenfalls wie die oben genannten Autofahrer über kurz oder lang auf die Nase fallen. Entscheidend ist doch aber, was unterm Strich übrig bleibt. Und da führen in der Summe beim Auto Gurt, Airbag, ABS usw. ebenso wie Warnungen bei Compileren, zu einem minimierten Risiko. Es ist auch nie Ziel gewesen, garantiert aller Probleme zu eliminieren. Das wird (wahrscheinlich) auch nie gelingen, da der Faktor Mensch unsere Welt einfach ausmacht. Aber man kann sich dem Ideal annähern.
@Michael (ein anderer) "Was er jedoch wunderbar machen kann, ist den Execution-Path zu analysieren." Können könnte er, aber scheinbar macht das keiner, den ich kenne. Z.B. passiert es oft, daß durch Schreibfehler Bedingungen konstant 0 oder 1 werden und der Compiler diese stillschweigend wegoptimiert. Da wäre eine Warnung durchaus angebracht. Auch jedes andere Wegoptimieren sollte angewarnt werden, z.B. leere Delayschleifen usw. Eine OR-Verknüpfung mehrerer UNDs ist aber quasi ein Standardkonstrukt, d.h. in der Regel kein Schreibfehler, deshalb ärgert mich eben diese Warnung. Am besten wäre natürlich, wenn man die Warnungen einzeln aus- und einschalten könnte, am allerbesten sogar auf einzelne Codeteile beschränkt (z.B. mittels pragma). Peter
Wenn in einem Compiler der Aufwand getrieben wird, einige spezielle Funktionen mit vararg-Argumenten auf korrekte Typisierung zu überprüfen, dann sollte auch ein Mechanismus geschaffen werden, diesen Aufwand auf andere vararg-Funktionen zu erweitern. Sonst werden folgende drei Beispiele unterschiedlich interpretiert: int printf(const char *, ...); printf("Das ist ein %d Fehler\n", "Fehler"); int MyOwnSpecialPrintf(const char *, ...); MyOwnSpecialPrintf("Das ist ein %d Fehler\n", "Fehler"); int MyVeryOwnSpecialPrintf(const char *, ...); MyVeryOwnSpecialPrintf("Das ist ein ###d Fehler\n", "Fehler"); Das erste Beispiel ist die Standardvariante, das zweite eine, die sich nur durch den Funktionsnamen unterscheidet, und das dritte eines, bei dem ein anders strukturierter Formatstring verwendet wird, was ja jemand aus-was-auch-immer für Gründen schick finden könnte. Der Compiler wird nur bei der ersten Variante motzen, und dann kann man's auch sein lassen. Typüberprüfung nur bei Verwendung einiger weniger Standardfunktionen? Nee, das ist 'ne Gurkenlösung. Übrigens: Welcher der auf dem Markt befindlichen C-Compiler ist überhaupt ein C99-Compiler? Üblich ist immer noch C89/90, also Ansi-C.
@Peter: > Am besten wäre natürlich, wenn man die Warnungen einzeln aus- und > einschalten könnte, am allerbesten sogar auf einzelne Codeteile > beschränkt (z.B. mittels pragma). Je nachdem wie fein granuliert Du's haben willst, ist -Wno-parentheses vielleicht was für Dich. Pragmas fände ich persönlich nicht so schön, weil es die Sache wieder compilerabhängig macht (da sie nicht vorgeschrieben sind könnte ein anderer Compiler nämlich was ganz furchtbar dummes machen, dürfen dürfte er es zumindest).
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.