Hi Leute! Ich programmiere erst seit kurzem mit C und habe relativ wenig Erfahrung damit. Ich habe Mal einen kleinen Georechner programmiert. Leider erhalte ich dauernd diese Meldungen: [Warning] overflow in implicit constant conversion [Warning] character constant too long for its type Ich würde mich freuen wenn mir jemand verständlich antwortet (damit es auch nicht-hardcore-programmierer verstehen). Das ist der Code: //Einbindung der Datei stdio.h #include <stdio.h> //Definition von pi, gerundet auf 100 Stellen nach dem Punkt #define pi 3.1415265358979323846264338327950288419716939937510582097494459230781640 628620899862803 //Beginn des Hauptprogramms int main(void){ Anfang :; //Definition der benötigten Variabeln und Arrays char zweidform, dreidform, beenden; float radius, flaeche, laenge, laenge1, laenge2, laenge3, breite, umfang, hoehe, volumen, seite[20], hseite[20], pyta[20], pflaeche[20], pflaeche2, Grundflaeche; int seiten, i, seitenbak, dimension; printf ("Wollen Sie ein (2)D oder (3)D Koerper berechnen?\n\n"); fflush (stdin); scanf ("%i",&dimension); if (dimension == 2) { printf ("Wollen Sie einen (K)reis, ein (R)echteck oder ein (D)reieck berechnen?\n"); fflush(stdin); scanf ("%c",&zweidform); //Switch nach Eingabe switch(zweidform) { case 'K': case 'k' : //Berechnung von Umfang und Fläche des Kreises printf ("Geben Sie den Radius an\n"); fflush (stdin); scanf ("%f",&radius); flaeche = pi * pow(radius,2); umfang = radius 2 pi; printf ("Der Umfang ist %10.2f\n", umfang); printf ("Die Flaeche ist %10.2f\n", flaeche); fflush(stdin); do { printf ("Wollen Sie beenden? (y/n)\n\n"); fflush (stdin); scanf ("%c",&beenden); if (beenden == 'y') { continue; } else if (beenden == 'n') { goto Anfang; } else { printf("Diese Eingabe war nicht korrekt.\n"); beenden = 'ungueltig'; } }while(beenden != 'y'); break; case 'R' : case 'r' : //Berechnung von Umfang und Fläche des Rechtecks printf ("Geben Sie die Laenge an\n"); fflush (stdin); scanf ("%f",&laenge); printf ("Geben Sie die Breite an\n"); fflush (stdin); scanf ("%f",&breite); flaeche = breite * laenge; umfang = (breite + laenge) * 2; printf ("Der Umfang ist %10.2f\n", umfang); printf ("Die Flaeche ist %10.2f\n\n\n", flaeche); fflush(stdin); do { printf ("Wollen Sie beenden? (y/n)\n\n"); fflush (stdin); scanf ("%c",&beenden); if (beenden == 'y') { continue; } else if (beenden == 'n') { goto Anfang; } else { printf("Diese Eingabe war nicht korrekt.\n"); beenden = 'ungueltig'; } }while(beenden != 'y'); break; case 'D' : case 'd' : //Berechnung von Umfang und Fläche des Dreiecks printf ("Geben Sie die Laengen der Seiten an, beginnend mit der unteren\n"); fflush (stdin); scanf ("%f",&laenge1); scanf ("%f",&laenge2); scanf ("%f",&laenge3); printf ("Geben Sie die Hoehe an\n"); fflush (stdin); scanf ("%f",&hoehe); flaeche = hoehe * laenge1 / 2; umfang = laenge1 + laenge2 + laenge3; printf ("Der Umfang ist %10.2f\n", umfang); printf ("Die Flaeche ist %10.2f\n\n\n", flaeche); fflush(stdin); do { printf ("Wollen Sie beenden? (y/n)\n\n"); fflush (stdin); scanf ("%c",&beenden); if (beenden == 'y') { continue; } else if (beenden == 'n') { goto Anfang; } else { printf("Diese Eingabe war nicht korrekt.\n"); beenden = 'ungueltig'; } }while(beenden != 'y'); break; default: printf("Diese Eingabe war nicht korrekt."); } } else if (dimension == 3) { printf ("Wollen Sie eine (K)ugel, ein (Q)ader oder eine (P)yramide berechnen?\n"); fflush(stdin); scanf ("%c",&dreidform); switch(dreidform) { case 'K' : case 'k' : //Berechnung von Volumen und Oberfläche der Kugel printf ("Geben Sie den Radius an\n"); fflush (stdin); scanf ("%f",&radius); flaeche = 4 pi pow(radius,2); volumen = 4/3 pi pow(radius,3); printf ("Das Volumen ist %10.2f\n", volumen); printf ("Die Oberflaeche ist %10.2f\n\n\n", flaeche); fflush(stdin); do { printf ("Wollen Sie beenden? (y/n)\n\n"); fflush (stdin); scanf ("%c",&beenden); if (beenden == 'y') { continue; } else if (beenden == 'n') { goto Anfang; } else { printf("Diese Eingabe war nicht korrekt.\n"); beenden = 'ungueltig'; } }while(beenden != 'y'); break; case 'Q' : case 'q' : //Berechnung von Volumen und Oberfläche des Quaders printf ("Geben Sie die Laenge an\n"); fflush (stdin); scanf ("%f",&laenge); printf ("Geben Sie die Breite an\n"); fflush (stdin); scanf ("%f",&breite); printf ("Geben Sie die Hoehe an\n"); fflush (stdin); scanf ("%f",&hoehe); volumen = breite laenge hoehe; flaeche = (breite * laenge + breite * hoehe + laenge * hoehe) * 2; printf ("Das Volumen ist %10.2f\n", volumen); printf ("Die Oberflaeche ist %10.2f\n\n\n", flaeche); fflush(stdin); do { printf ("Wollen Sie beenden? (y/n)\n\n"); fflush (stdin); scanf ("%c",&beenden); if (beenden == 'y') { continue; } else if (beenden == 'n') { goto Anfang; } else { printf("Diese Eingabe war nicht korrekt.\n"); beenden = 'ungueltig'; } }while(beenden != 'y'); break; default: printf("Diese Eingabe war nicht korrekt.\n"); goto Anfang; } } else { printf("Diese Eingabe war nicht korrekt.\n"); goto Anfang; } getchar(); return 0; }
Man kann den Code erstens vernünftig formatieren und zweitens kann man Code dieser Länge als Anhang anfügen, was darauf hindeutet, dass Du die Forenregeln vor dem Absenden nicht gelesen hast! Abgesehen davon gehört zu einer Fehler- oder Warnmeldung immer der Hinweis auf die Codezeile, die der Compiler moniert! Ein kurzes Drüberschauen lässt mich allerdings vermuten, dass es sich um die (mehrfach vorkommende) Zeile
1 | beenden = 'ungueltig'; |
handelt, was kein gültiges C ist. In einfache Hochkommata werden nur einzelne Character eingeschlossen. Ein Zeichenstring kommt in doppelte Hochkommata (Anführungszeichen). In C kann man aber auch keinen String einer Variablen zuweisen, weshalb das so überhaupt nicht geht.
Lass doch einfach alle Zeilen
1 | beenden = 'ungueltig'; |
weg. Sie werden nicht benötigt. An der Stelle ist nur wichtig, dass die Variable einen von 'y' verschiedenen Wert hat. Das ist aber durch die vorangegangenen Abfragen schon sicher gestellt. Anderer, nicht so wichtiger Punkt:
1 | printf ("Wollen Sie beenden? (y/n)\n\n"); |
Ist die Benutzerführung des Programms deutsch oder englisch? ;-)
Also aus dem Gedächtnis schaffe ich: 3.141592653589 Das hat hat immer noch für alles gereicht.
@VMgolf: Der Beitrag des Vorposters bringt mich auf etwas lustiges: Von deinen 100 Nachkommastellen sind gerade mal die ersten 5 richtig :D Das lange pi ist übrigens nicht die Ursache für die Warnung. Das hat wohl derjenige, der das ursprünglich vermutet hat, ebenfalls erkannt ;-)
... außerdem sind es nur 85 Nachkommastellen.
yalu wrote:
> Von deinen 100 Nachkommastellen sind gerade mal die ersten 5 richtig :D
Vier. Das fünfte wäre eine 9, die fehlt. Danach folgt dann der Rest
der Mantisse.
fflush(stdin) führt übrigens zu undefiniertem Verhalten. Laut Standard ist es verboten, fflush auf Eingabe-Streams aufzurufen. Wenn dein Programm zuverlässiger funktionieren soll, würde ich das weglassen.
Ich verwende Dev-C++ und das ganze funzt nur mit fflush(stdin). @Pi Fanatiker: Sucht euch ein Hobby...
Jörg Wunsch schrieb: > yalu wrote: > >> Von deinen 100 Nachkommastellen sind gerade mal die ersten 5 richtig :D > > Vier. Das fünfte wäre eine 9, die fehlt. Danach folgt dann der Rest > der Mantisse. Huch, da habe ich doch bei der letzten Tastaturreinigung doch tatsächlich die Tastenkappen für die 4 und die 5 vertauscht =:-o Wann wird das M_PI endlich mal in den Standard aufgenommen? Dann könnte man sich solche Diskussionen sparen :)
VWgolf wrote:
> Ich verwende Dev-C++ und das ganze funzt nur mit fflush(stdin).
Absence of evidence is no evidence of absence.
Undefiniertes Verhalten bedeutet ja nicht, dass es nicht auch
funktionieren könnte, aber es ist und bleibt trotzdem Unsinn.
> Ich verwende Dev-C++ und das ganze funzt nur mit fflush(stdin).
In anderen Laufzeitumgebungen funzt es weder ohne noch mit fflush().
Besser: Immer eine ganze Eingabezeile mit gets() in ein char-Array
einlesen, danach mit sscanf() die gewünschten Dinge herausklamüsern.
Noch besser: An Stelle von gets() fgets() mit stdin als Eingabestrom
verwenden, das hält eventuelle Hacker fern ;-)
Vielen Dank, für die inputs. Ich wäre aber noch froh über ein Beispiel. Ich hab das so verstanden: printf ("Wollen Sie ein (2)D oder (3)D Koerper berechnen?\n\n"); fgets(stdin); sscanf ("%i",&dimension); Hast du's so gemeint? fgets kennt es gar nicht, brauche ich ein include? wenn ich gets benutze kommt ein Error Fenster.
> Ich wäre aber noch froh über ein Beispiel.
1 | #include <stdio.h> |
2 | |
3 | int main(void) { |
4 | char eingabezeile[80]; |
5 | int dimension; |
6 | |
7 | // Eingabe von Zahlenwerten
|
8 | fgets(eingabezeile, sizeof eingabezeile, stdin); |
9 | sscanf(eingabezeile, "%i", &dimension); |
10 | printf("%d\n", dimension); |
11 | |
12 | // Eingabe von einzelnen Zeichen zur Menüauswahl
|
13 | fgets(eingabezeile, sizeof eingabezeile, stdin); |
14 | switch(eingabezeile[0]) { |
15 | case 'j': |
16 | case 'J': |
17 | printf("Jawohl\n"); |
18 | break; |
19 | case 'n': |
20 | case 'N': |
21 | printf("Nee\n"); |
22 | break; |
23 | default:
|
24 | printf("Häh\n"); |
25 | }
|
26 | return 0; |
27 | }
|
> fgets kennt es gar nicht, brauche ich ein include?
stdio.h, das brauchst du aber für scanf auch.
Gabs nicht auch mal getc() ?! Für einzelne Zeichen säh das dann schöner aus.
Vielen Dank, das funktioniert gut! Eine letzte Frage habe ich noch. Wann ist es nötig dieses fgets zu benutzen? Immer zwischen printf und sscanf?
Ausserdem erhalte ich diese Warnungen: [Warning] passing arg 1 of `fgets' from incompatible pointer type [Warning] passing arg 1 of `sscanf' from incompatible pointer type
> Wann ist es nötig dieses fgets zu benutzen? Immer zwischen printf > und sscanf? Vor dem sscanf. fgets liest eine komplette Eingabezeile, aus der anschließend die gewünschten Daten (z.B. ein Integer-Wert) mit sscanf extrahiert werden. Der Vorteil dieser Vorgehensweise liegt darin, dass sämtliche Zeichen einer Zeile bis zum Zeilenvorschub am Ende eingelesen werden. Was nicht durch sscanf verarbeitet wird, wird einfach verworfen und stört nicht mehr. Benutzt man nur scanf für die Eingabe, kann folgendes passieren: Mit scanf("%i", &n) wird eine Zahl gelesen. Dabei werden alle Zeichen bis zur letzten Ziffer der Zahl gelesen, aber nicht mehr. Insbesondere der Zeilenvorschub '\n' bleibt im Eingabestrom stehen. Folgt nun ein scanf("%c", &z), wird das nächste Zeichen im Eingabestrom, also das '\n" in die Variable z gelesen, was aber nicht beabsichtigt ist. Eigentlich sollte ja das erste Zeichen der nächsten Zeile gelesen werden. Ok, man könnte als Workaround nach dem Einlesen eines Zahlenwerts immer einen scanf("%c", &dummy) oder ein getchar() folgen lassen um den Zeilenvorschub zu überlesen. Was passiert aber, wenn der Benutzer ans Ende der Zeile noch ein paar Leerzeichen anfügt? Diese müssten dann ebenfalls überlesen werden. Das gleiche Problem hat man, wenn das scanf("%c" &z) durch z=getchar() oder z=getc(stdin) ersetzt. Das Problem kann auf manchen Systemen mit einem fflush() vor dem scanf() beseitigt werden, aber eben nicht auf allen. Mit der fgets/sscanf-Methode ist einfach sichergestellt, dass bei jeder neuen Eingabezeile keine störenden Überbleibsel aus der letzten Zeile vorhanden sind. Mit der fgets/sscanf-Methode ist einfach sichergestellt, dass bei jeder neuen Eingabezeile, keine störenden Überbleibsel aus der letzten Zeile vorhanden sind. > [Warning] passing arg 1 of `fgets' from incompatible pointer type Wahrscheinlich hast du die Variable eingabezeile falsch definiert.
Vielen Dank. Du hattest Recht. Es funktioniert jetzt. Das einzige Problem, welches ich noch habe ist, dass ich 2 Mal 'j' tippen muss um es zu beenden. Ich habe keinen Plan, weshalb... case 'K': case 'k' : //Berechnung von Umfang und Fläche des Kreises printf ("Geben Sie den Radius an\n"); fgets(eingabezeile, sizeof eingabezeile, stdin); sscanf(eingabezeile, "%f", &radius); flaeche = pi * pow(radius,2); umfang = radius 2 pi; printf ("Der Umfang ist %10.2f\n", umfang); printf ("Die Flaeche ist %10.2f\n", flaeche); do { printf ("Wollen Sie beenden? (j/n)\n"); fgets(eingabezeile, sizeof eingabezeile, stdin); sscanf(eingabezeile, "%c", &beenden); if (beenden == 'j') { continue; } else if (beenden == 'n') { goto Anfang; } else { printf("Diese Eingabe war nicht korrekt.\n"); } }while(beenden != 'j'); break;
Continue macht ja, dass die Schleife verlassen wird. Wenn man die while Schleife verlässt per continue, geht es ja automatisch zum break nach der Schleife. Etwa nicht? Wie auch immer, es macht keinen Unterschied ob dort 'continue' oder 'break' steht.
> Continue macht ja, dass die Schleife verlassen wird.
Continue verlässt die Schleife nicht, sondern springt an deren Ende.
Da dort aber die Abbruchbedingung erfüllt ist, wird sie in deinem Fall
tatsächlich verlassen.
Ich schätze, es ist einfach das getchar() am Programmende, das eine
weitere Eingabe erwartet. Nimm es heraus, und schau, was passiert.
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.