Forum: Compiler & IDEs [Warning] character constant is too long for it's type


von VWgolf (Gast)


Lesenswert?

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;
}

von Johannes M. (johnny-m)


Lesenswert?

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.

von yalu (Gast)


Lesenswert?

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? ;-)

von Pi (Gast)


Lesenswert?

Also aus dem Gedächtnis schaffe ich:
3.141592653589

Das hat hat immer noch für alles gereicht.

von VWgolf (Gast)


Lesenswert?

Vielen Dank!

& entschuldigung

von yalu (Gast)


Lesenswert?

@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
;-)

von yalu (Gast)


Lesenswert?

... außerdem sind es nur 85 Nachkommastellen.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

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.

von spell_checker (Gast)


Lesenswert?

its type

von another_spell_checker (Gast)


Lesenswert?

That's right!

von Chris (Gast)


Lesenswert?

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.

von VWgolf (Gast)


Lesenswert?

Ich verwende Dev-C++ und das ganze funzt nur mit fflush(stdin).

@Pi Fanatiker: Sucht euch ein Hobby...

von yalu (Gast)


Lesenswert?

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 :)

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

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.

von yalu (Gast)


Lesenswert?

> 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 ;-)

von VWgolf (Gast)


Lesenswert?

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.

von yalu (Gast)


Lesenswert?

> 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.

von Sven P. (Gast)


Lesenswert?

Gabs nicht auch mal getc() ?! Für einzelne Zeichen säh das dann schöner 
aus.

von VWgolf (Gast)


Lesenswert?

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?

von VWgolf (Gast)


Lesenswert?

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

von yalu (Gast)


Lesenswert?

> 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.

von VWgolf (Gast)


Lesenswert?

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;

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

break mit continue verwechselt?

von VWgolf (Gast)


Lesenswert?

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.

von yalu (Gast)


Lesenswert?

> 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.

von VWgolf (Gast)


Lesenswert?

Ja, das war der Grund.
Vielen Dank.

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
Noch kein Account? Hier anmelden.