www.mikrocontroller.net

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


Autor: VWgolf (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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;
}

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht 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
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.

Autor: yalu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Lass doch einfach alle Zeilen
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:
printf ("Wollen Sie beenden? (y/n)\n\n");

Ist die Benutzerführung des Programms deutsch oder englisch? ;-)

Autor: Pi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also aus dem Gedächtnis schaffe ich:
3.141592653589

Das hat hat immer noch für alles gereicht.

Autor: VWgolf (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielen Dank!

& entschuldigung

Autor: yalu (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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
;-)

Autor: yalu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
... außerdem sind es nur 85 Nachkommastellen.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: spell_checker (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
its type

Autor: another_spell_checker (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
That's right!

Autor: Chris (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: VWgolf (Gast)
Datum:

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

@Pi Fanatiker: Sucht euch ein Hobby...

Autor: yalu (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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 :)

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: yalu (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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 ;-)

Autor: VWgolf (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: yalu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Ich wäre aber noch froh über ein Beispiel.
#include <stdio.h>

int main(void) {
  char eingabezeile[80];
  int dimension;

  // Eingabe von Zahlenwerten
  fgets(eingabezeile, sizeof eingabezeile, stdin);
  sscanf(eingabezeile, "%i", &dimension);
  printf("%d\n", dimension);

  // Eingabe von einzelnen Zeichen zur Menüauswahl
  fgets(eingabezeile, sizeof eingabezeile, stdin);
  switch(eingabezeile[0]) {
    case 'j':
    case 'J':
      printf("Jawohl\n");
      break;
    case 'n':
    case 'N':
      printf("Nee\n");
      break;
    default:
      printf("Häh\n");
  }
  return 0;
}

> fgets kennt es gar nicht, brauche ich ein include?

stdio.h, das brauchst du aber für scanf auch.

Autor: Sven P. (haku) Benutzerseite
Datum:

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

Autor: VWgolf (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: VWgolf (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: yalu (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: VWgolf (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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;

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
break mit continue verwechselt?

Autor: VWgolf (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: yalu (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: VWgolf (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja, das war der Grund.
Vielen Dank.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.