Bytes auslesen und in ein Array schreiben "C"

Gast #1964732
Lesenswert?
• ▲
▼
Hallo Leute!

Ich habe ein Int-Array das ist z. B. so gefüllt ist 
[10000;-10000;5000;-2344;...;x]

Nun zu meinem Problem. Der Int-Datentyp besteht doch aus 2 Byte. Ich 
möchte nun die zwei Bytes aus dem Int-Array ausgewählter Zahlen auslesen 
und in ein char-Array schreiben.

Ich vermute man macht das am besten mit Zeigern, aber damit kenne ich 
mich noch nicht so gut aus.

Würde mich über einen Hinweis freuen.
mfg Jakob
#1964785
Lesenswert?
• ▲
▼
Jetzt verrat mir mal einer, warum hier zum Teufel immer verquastere und 
implementationsabhängigere Codevarianten auf so ein gängiges Problem 
losgelassen werden. Wieviele Gigabytes musst Du denn pro Sekunde 
umkodieren?

Wenn es absolut auf Geschwindigkeit ankommt, dann doch gleich jede Scham 
über Bord geworfen und so:
1
int aiIrgendwas[NUM_EL_INT];
2
char pcMirGraust = (char*)aiIrgendwas;
3

4
aiIrgendwas[0] = 4711;
5
/* pcMirGraust[0] und pcMirGraust[1] können Daten enthalten, die was mit 4711 zu tun haben */

Wenn Du irgendwie Kontrolle über das behalten willst was Du da tust, 
solltest Du so etwas tun:
1
#include "MISRATYPES.H" /* Oder wie auch immer das in Deiner Welt heisst */
2

3
int16_t ai16Irgendwas[NUM_EL_INT];
4
uint8_t  au8Serialisiert[NUM_EL_INT*2];
5

6
for (int i=0; i<MUM_EL_INT; ++i)
7
{
8
  au8Serialisiert[i*2]   = (uint8_t)(ai16Irgendwas[i]&0xFF);
9
  au8Serialisiert[i*2+1] = (uint8_t)(ai16Irgendwas[i]>>8);
10
}

Das ist wenigstens soweit durchschaubar, Du weißt immerhin, wo High- und 
wo Low-Byte stehen, etc. Aber natürlich ist der Code a) lesbar und b) 
nicht superperformant, also überhaupt kein richtiges C sondern nur 
verkleidetes Pascal...

Aber das schreib ich nur, weil ich weiß, dass es keinen interessiert. 
Ich lebe ja davon derartige Schlampigkeiten zu suchen.

Grüße,
  Stefan
#1964805
Lesenswert?
• ▲
▼
Stefan Hennig schrieb:
> Jetzt verrat mir mal einer, warum hier zum Teufel immer verquastere und
> implementationsabhängigere Codevarianten

Über Geschmack kann man streiten.
Aber erstens wollte der TO eine Zeigerlösung haben, zweitens: wo
bitte ist das (von der Vorgabe sizeof(int)==2 abgesehen)
implementationsabhängig?

Stefan Hennig schrieb:
> Wenn es absolut auf Geschwindigkeit ankommt, dann doch gleich jede Scham
> über Bord geworfen und so:int aiIrgendwas[NUM_EL_INT];
> char pcMirGraust = (char*)aiIrgendwas;
>
> aiIrgendwas[0] = 4711;
>

So wird es jedenfalls nicht gehen, was deine Abneigung gegen
Zeiger natürlich bestätigt :-)
#1964860
Lesenswert?
• ▲
▼
Klaus Wachtler schrieb:
> Stefan Hennig schrieb:
>> Ich lebe ja davon derartige Schlampigkeiten zu suchen.
>
> Das nehme ich natürlich persönlich :-)

Danke für das Smiley. Persönlich wars bestimmt nicht gemeint.

Mein Beispielcode ist natürlich falsch, mindestens fehlt ein 
Pointer-Stern.
Ansonsten bitte ich, meine unterschwellige Gereiztheit zu entschuldigen, 
ich bin im Moment neben dem üblichen Weihnachtsstress noch im 
Projektstress, der sich zumindest etwas hätte abmildern lassen, wenn 
jeder, sagen wir, etwas defensiver programmiert hätte und nicht immerzu 
irgendwelche Annahmen über irgendetwas gemacht hätte, das im vor-vorigen 
Projekt wahr gewesen sein mochte.

Nichts für ungut,
   Stefan.
#1964883
Lesenswert?
• ▲
▼
Habe ich auch nicht so ernst genommen, aber Pfusch lasse ich
auch nicht gerne auf mir sitzen.
Sonst bin ich nicht eitel, aber da manchmal schon (was nicht
davor schützt, trotzdem Fehler zu machen - leider).

Defensives Programmieren kann ich aber auch jederzeit unterstützen,
dagegen sage ich gar nichts.
Gast #1964887
Lesenswert?
• ▲
▼
Wie wäre denn eine Lösung mit Union?

Dabei ist es egal ob ein int jetzt 2, 4 oder 8 Byte groß ist, solange 
die Byteorder Little-Endian ist.
1
union {
2
 int int_v;
3
 short short_v;
4

5
 struct {
6
  char low;
7
  char high;
8
 } char_v;
9

10
} converter;

Wobei ich auch hier Datentypen mit vorgegebener Größe bevorzugen würde, 
also int16_t bzw. int8_t.
Gast #1964941
Lesenswert?
• ▲
▼
Klaus Wachtler schrieb:
> char carr[2];
>     carr[0] = ((char *)&intarr[i])[0];
>     carr[1] = ((char *)&intarr[i])[1];


Hallo ich habe das so gemacht und er gibt mir ein Herz :) aus. Ich 
dachte da kommt irgendwie eine Hexzahl heraus?

Dem Problem mit der Bytelänge bei int, kann ich doch umgehen wenn ich 
einfach short nehme oder?
Gast #1964955
Lesenswert?
• ▲
▼
Du musst dir schon überlegen wie du den char ausgibst:

printf("%c", chrr[0]); -> Zeigt dir das Ascii Zeichen an (das Herz).

printf("%d", chrr[0]); -> Zeigt dir den Dezimalwert an.

printf("%x", chrr[0]); -> Zeigt dir den Hexadezimalwert an.
Gast #1964971
Lesenswert?
• ▲
▼
Und tu dir bitte den Gefallen und benutze definierte Datentypgrößen 
(int16_t).

Bei einem int und short ist nur sicher das sie mindestens 16 Bit haben, 
sowie das ein long mindestens so groß ist wie ein int, aber mindestens 
32 Bit hat.

Daraus hat sich auf 16-Bit Systemen die Praxis eingebürgert char, short, 
int und long die Größen 8, 16, 16, 32 zu geben; auf 32-Bit Systemen 
jedoch 8, 16, 32, 32.

Aber drauf verlassen das ein short oder int jetzt 16 oder 32 Bit hat, 
kannst du dich nicht!
#1964988
Lesenswert?
• ▲
▼
Und schon gar nicht, unter keinen Umständen, nimmt man den Datentyp 
'char' her, wenn man mit Bytes arbeitet!


Am besten gewöhnt man sich von vrne herein gleich mal die Sichtweise an, 
dass es in C 3 verschiedene Character-Datentypen gibt


    char
    signed char
    unsigned char


Aber auch hier bevorzugt man für die letzten beiden die Schreibweise 
int8_t bzw uint8_t
Gast #1965192
Lesenswert?
• ▲
▼
Klaus Wachtler schrieb:
> Defensives Programmieren

Leider klingt das so langweilig, dass Jungspunden (ok, ist 
Ansichtssache) wie mir dabei die Füsse einschlafen ;)
Könnt ihr alten Hasen da vielleicht ein "cooleres" Wort für finden?

Klaus Wachtler schrieb:
> Bevor du übrigens mit ganz wilden Konstruktionen liebäugelst,

DAS klingt doch schon viel reizvoller, wer möchte nicht Beherrscher 
"wilder Konstrukte" sein? ;)
Gast #1965198
Lesenswert?
• ▲
▼
@Jakob

Sorry, mein Beitrag ist sicher keine große Hilfe für dich gewesen.

Klaus Wachtler schrieb:
> Jakob schrieb:
>> Ich kenne die Grundlagen von C und habe meine Schwierigkeiten damit.
>
> Dann kennst du dir Grundlagen nicht genug :-)
>

Damit hat Klaus aber das Wesentliche gesagt. Wenn dann noch Fragen 
auftauchen, immer her damit.
Gast #1965263
Lesenswert?
• ▲
▼
Hi hab noch ne Menge fragen :)
1
#include <stdio.h>
2

3
__int16 werte[100];
4
int n;
5
char test[10];
6

7
int main()
8
{
9
  for (n=0; n<100; n++)
10
  {
11
    werte[n]=n;
12
  }
13

14
  werte[3]=16384;
15
  werte[4]=-16384;
16

17
  test[0]=((char *) &werte[3])[0];
18

19

20
printf("%x\n", werte[0]);
21
printf("%x\n", werte[1]);
22
printf("%x\n", werte[2]);
23
printf("%x\n", werte[3]);
24
printf("%x\n", werte[4]);
25
printf("%x\n", test[0]);
26

27
getchar();
28
}

Die Ausgabe macht:
0    //ja alles klar
1    //ja alles klar
2    //ja alles klar
4000 //ja alles klar
FFFFC000 //nein ich erwarte C000 2Byte das sind 4 Byte !?
0    //ich erwarte 4000

Warum klappt das nicht bei werte[4] und test[0] ?
#1965277
Lesenswert?
• ▲
▼
Jakob schrieb:

> 4000 //ja alles klar
> FFFFC000 //nein ich erwarte C000 2Byte das sind 4 Byte !?

Das ist aber printf egal.
printf erwartet bei %x einen int. Und ein int ist auf deinem PC nun mal 
4 Bytes groß


> 0    //ich erwarte 4000

Solange du das weiter oben Gesagte über den Datentyp char nicht 
beherzigst wird das nichts. Des weiteren wirst du mit 4000 in einem Byte 
sowieso Schiffbruch erleiden. 256 ist das Maximum.
#1965318
Lesenswert?
• ▲
▼
Karl heinz Buchegger schrieb:
> Jakob schrieb:
>> 0    //ich erwarte 4000
>
> Solange du das weiter oben Gesagte über den Datentyp char nicht
> beherzigst wird das nichts. Des weiteren wirst du mit 4000 in einem Byte
> sowieso Schiffbruch erleiden. 256 ist das Maximum.

Das würde hier noch passen: ein Byte ist 0, dass andere 64.

An den TO: Null kommt raus, da die Byte-Reihenfolge nicht Big-Endian, 
sondern Little-Endian ist d.h. ((char *) &werte[3])[1] == 0x40
Gast #1965661
Lesenswert?
• ▲
▼
hab mich nochmal durch die Grundlagen geforstet. Ich will ja immer noch 
ein Array mit Bytes haben. Sollte C++ sein :)
1
struct array2byte
2
{
3
unsigned char high;
4
unsigned char low;
5
}
6

7
struct array10byte
8
{
9
array2byte array[3];
10
}

Jetzt hab ich doch ein Array mit wo ich schön 10 Byte reinschreiben kann 
oder?

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren