Forum: Mikrocontroller und Digitale Elektronik char und int_8t nicht das selbe?


von Matthias F. (frank91)


Lesenswert?

Hallo

ich dachte immer char und int_8t wäre das selbe.
Dieses C Programm zeigt mir gerade, dass es wohl nicht so ist^^

Ich habe ein Programm welches über die Serie Schnittstelle Daten an 
meinen Controller sendet. Allerdings scheint dieses Programm Probleme 
mit Sonderzeichen zu haben.
Statt ü sendet es die Zahl 195 anschließend 188.
Statt ü sendet es die Zahl 195 anschließend 159.

Das unten stehende Programm funktioniert so. Es passt diesen Fehler 
entsprechend an.

Schreibe ich allerdings statt
char empfangen =0;
das hier
int_8t empfangen =0;
funktioniert meine Auswertung nicht mehr.
Die Zeichen 195 und 188 bzw 159 werden aber trotzdem in mein Array
empfangspuffer übertragen.

Wie kann das sein?
1
ISR(USARTC1_RXC_vect)
2
{  
3
  char empfangen =0;
4
  empfangen = USARTC1.DATA;
5
  
6
  if (paket_wird_empfangen ==1)
7
  {
8
    if (empfangen == '$') //36Wenn das Schlusszeichen $ empfangen wurde
9
    {
10
      paket_empfangen =1;
11
      paket_wird_empfangen =0;
12
    }
13
    else
14
    {
15
      if(empfangen!= 195) //Anfangszeichen für Sonderzeichen nicht werten
16
      {
17
        //Sonderzeichen anpassen
18
        if(empfangen ==188) empfangen ='ü';
19
        if(empfangen ==159) empfangen ='ß';
20
        
21
        empfangspuffer[empfangspuffer_zaehler] = empfangen; 
22
        empfangspuffer_zaehler++;
23
      }
24
      
25
    }
26
  }
27
  
28
  if (empfangen == '#')  //35 =#
29
  {
30
    paket_wird_empfangen =1;
31
  }
32
  
33
}

von Peter II (Gast)


Lesenswert?

Matthias Frank schrieb:
> ich dachte immer char und int_8t wäre das selbe.

char != int_8t != uint8_t

wobei man abhängig vom Compiler ist ob ein char singed oder unsigend 
ist. Dazu kommt jetzt noch das Problem mit der Codepage. Ü ist nicht 
überall gleich. Sinnvoll ist es hierfür gleich den passende int wert zu 
verwenden.

von Fritz G. (fritzg)


Lesenswert?

Du bekommst deine Umlaute anscheinend als UTF-8, das sind 2 Byte für 
diese Zeichen.

von Matthias F. (frank91)


Lesenswert?

> char != int_8t

Aber beim Atmel Studio ist es doch das selbe? Oder auch nicht?

von Peter II (Gast)


Lesenswert?

Matthias Frank schrieb:
> Aber beim Atmel Studio ist es doch das selbe? Oder auch nicht?

nein char ist immer was anders. ob es signed oder unsigned ist kann man 
im Compiler einstellen.

man sollte sie nicht als gleich ansehen.

von Matthias F. (frank91)


Lesenswert?

tatsächlich^^

wenn ich signed char schreibe geht es wieder nicht.

also ist ein char wohl ein uint_8t

von Matthias F. (frank91)


Lesenswert?

> nein char ist immer was anders. ob es signed oder unsigned ist kann man
> im Compiler einstellen.

Achso ok. Wieder was gelernt xD

von Peter II (Gast)


Lesenswert?

For gcc, the default is signed, but you can modify that with 
-funsigned-char. note: for gcc in Android NDK, the default is unsigned. 
You can also explicitly ask for signed characters with -fsigned-char.

On MSVC, the default is signed but you can modify that with /J.

von Johannes M. (johannesm)


Lesenswert?

int8_t hat einen Wertebereich von -128 bis +127 für dein oben genanntes 
Beispiel wäre das schon mal nicht Zielführend. Ich würde die eindeutigen 
Datentypen benutzen, dann hat man die Probleme nicht.

von Fritz G. (fritzg)


Lesenswert?

Kann dein Compiler keine Warnungen? Bei mir kommt:
1
main.c:46:40: error: character too large for enclosing character literal type
2
        if(empfangen ==188) empfangen ='ü';
3
                                       ^
4
main.c:47:40: error: character too large for enclosing character literal type
5
        if(empfangen ==159) empfangen ='ß';
6
                                       ^
7
main.c:43:17: warning: comparison of constant 195 with expression of type 'char' is always true
8
      [-Wtautological-constant-out-of-range-compare]
9
    if(empfangen!= 195) //Anfangszeichen für Sonderzeichen nicht werten
10
       ~~~~~~~~~^  ~~~
11
main.c:46:22: warning: comparison of constant 188 with expression of type 'char' is always false
12
      [-Wtautological-constant-out-of-range-compare]
13
        if(empfangen ==188) empfangen ='ü';
14
           ~~~~~~~~~ ^ ~~~
15
main.c:47:22: warning: comparison of constant 159 with expression of type 'char' is always false
16
      [-Wtautological-constant-out-of-range-compare]
17
        if(empfangen ==159) empfangen ='ß';

Warnungen sind nicht zum Spaß da.

von Peter II (Gast)


Lesenswert?

Fritz Ganter schrieb:
> Kann dein Compiler keine Warnungen? Bei mir kommt:
> main.c:46:40: error: character too large for enclosing character literal type

kann es sein da du eine utf8 Datei erstellt hast? Diese Meldung sollte 
nicht kommen.

von Fritz G. (fritzg)


Lesenswert?

Sorry, nehme alles zurück, der avr-gcc warnt tatsächlich nicht, dass der 
Vergleich immer wahr/falsch ist.

Ich habe gcc aufgerufen, aber gcc ist bei mir gar nicht gcc.

von Fritz G. (fritzg)


Lesenswert?

@Peter: ja. Aber eigentlich geht es mir um
1
main.c:43:17: warning: comparison of constant 195 with expression of type 'char' is always true
was anscheinend auch nicht mit -Wall kommt. Das ist echt nicht gut!

von Fritz G. (fritzg)


Lesenswert?

Ich habe es gefunden:

Schreibe -Wtype-limits in deine Compiler-Flags rein, dann bekommst du 
deswegen eine Warnung. Ist anscheinend nicht in -Wall enthalten.

von Axel S. (a-za-z0-9)


Lesenswert?

Matthias Frank schrieb:
> ich dachte immer char und int_8t wäre das selbe.

Kann so sein, muß aber nicht.

Ein Ärgernis (IMHO) bei C ist, daß die Standard-Datentypen so schwammig 
definiert sind:

char - kann ein Zeichen halten
int - Ganzzahl-Typ mit (ca.) der Bitbreite der CPU

Weil man für viele Anwendungen aber Typen mit genau bekannter Bitbreite 
und signedness (ist bei char z.B. unbestimmt) braucht, hat man mit C99 
das System-Headerfile stdint.h [1] eingeführt, das Integertypen mit 
vorhersagbarer Bitbreite und Signedness definiert.

[1] https://en.wikibooks.org/wiki/C_Programming/C_Reference/stdint.h

von Nase (Gast)


Lesenswert?

Fritz Ganter schrieb:
> was anscheinend auch nicht mit -Wall kommt. Das ist echt nicht gut!

-Wextra

von Michael R. (Firma: Brainit GmbH) (fisa)


Lesenswert?

Fritz Ganter schrieb:
> Schreibe -Wtype-limits in deine Compiler-Flags rein, dann bekommst du
> deswegen eine Warnung. Ist anscheinend nicht in -Wall enthalten.

Korrekt, -Wall aktiviert das nicht, aber -Wextra. Bei mir sind 
grundsätzlich immer beide aktiv, Code der Warnungen wirft wird nicht 
committed, sprich Warnungen werden immer alle bereinigt.

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.