Auf Char[2] als Integer zugreifen
-
So hab ich's probiert:
char teststr[2];
Dann wird von einer Datei eine 2-Byte-Folge in den String gelesen. Bis dahin klappt alles. Wenn ich auf die einzelnen Chars bzw. Bytes zugreif krieg ich die richtigen Werte ausgegeben.
Im Beispiel stehen im String die Werte 1 und 0 (nicht "0" und "1").cout<<int(teststr[0]); //Ausgabe: 1 cout<<int(teststr[1]); //Ausgabe: 0
Da es sich hierbei um eine in Little Endian gespeicherte Zahl handelt, dreh ich die Folge um, in Big Endian. Aus 1,0 wird 0,1. So, und jetzt probier ich nochmal auf die kompletten 2 Bytes zuzugreifen. Und es kommt irgendwas wie 1488 oder so raus:
cout<<int(teststr); //Ausgabe: 1488 (o.Ä., vor allem falsch)
Warum?
-
Ich will aus ner Wave-Datei en paar Daten auslesen, hier erstmal die Anzahl der Kanäle.
Hier is der komplette Quelltext:#include <stdio.h> #include <conio.h> #include <stdlib.h> const long BytePosChannels = 22; FILE *FileSrc; char FileNameSrc[12] = "TestSrc.wav"; char ChannelsSrc[2]; int ConvertEndian(char Str[4], int StrLength) { int x; char TempStr[4]; for(x=0;x<StrLength;x+=1) TempStr[x] = Str[x]; for(x=0;x<StrLength;x+=1) Str[x] = TempStr[StrLength-1-x]; return 0; } int main (void) { clrscr(); printf("Opening file '"); printf(FileNameSrc); printf("'..."); if ((FileSrc = fopen(FileNameSrc,"r")) != NULL) { printf("OK\nReading number of channels..."); fseek(FileSrc,BytePosChannels,0); fread(ChannelsSrc,2,1,FileSrc); ConvertEndian(ChannelsSrc,2); //so, und hier sollte dann die Ausgabe kommen fclose(FileSrc); } else { printf("Error\nPress a key to exit program"); getch(); exit(0); } getch(); }
-
the_MUKe schrieb:
cout<<int(teststr); //Ausgabe: 1488 (o.Ä., vor allem falsch)
Warum?
Ganz einfach!
int(teststr[0]) heißt nichts anderes als, wandle das Zeichen in int um, dass in teststr[0] enthalten ist.
int(teststr) heißt nicht anders, als, wanlde die Adresse als int aus, azuf die teststr zeigt, bzw. die Adresse wo teststr[0] sich befindet! Das sind 2 unterschiedliche Objekte, also 2 unterschiedliche Ausgaben.
Und was hat cout mit C zu tun?
Und conio.h in ANSI C Forum?
-
<OFF-TOPIC>
Also welche zusätzlichen Includes in einem code sind, sollte doch egal sein. Die Frage ist auf alle Fälle standardiger Natur(kühne Wortschöpfung).
Warum sollte man extra den Code noch mal kürzen/abändern, nur damit der Code 100% ANSI-kompilant ist, um hier präsentiert werden zu dürfen?! Ich denke, so peniebel muss man nicht sein.
Peniebel bin ich bei dem hier: "vor allem falsch"
Falsch ist es auf keinen Fall! Der Computer macht keine Fehler, dazu fehlt ihm die Intelligenz! Die Ausgabe entspricht nicht dem Erwartetem!
</OFF-TOPIC>
-
the_MUKe schrieb:
Da es sich hierbei um eine in Little Endian gespeicherte Zahl handelt, dreh ich die Folge um, in Big Endian. Aus 1,0 wird 0,1. So, und jetzt probier ich nochmal auf die kompletten 2 Bytes zuzugreifen. Und es kommt irgendwas wie 1488 oder so raus:
Warum?ausgabe von 2 bytes als big/little geht sinngemäss so:
int main() { char teststr[2] = {1,0}; unsigned int big_endian = teststr[0]*256 + teststr[1]; unsigned int little_endian = teststr[0] + teststr[1]*256; printf ("%d %d\n", big_endian, little_endian); }
-
Erstmal danke.
Diese Lösung ist ganz gut:
int main() { char teststr[2] = {1,0}; unsigned int big_endian = teststr[0]*256 + teststr[1]; unsigned int little_endian = teststr[0] + teststr[1]*256; printf ("%d %d\n", big_endian, little_endian); }
Wobei ich weiß wie ich mir die Werte berechnen kann.
Aber warum krieg ich etwas anderes ausgegeben wenn ich auf einmal auf beide Bytes zugreif als wenn ich jeweils auf jedes einzeln zugreif?
-
Wenn du auf ein Byte zugreifst, wird das als char interpretiert (also ein Zeichen). Beim integer handelt es sich dann bei der Ausgabe um eine Zahl...
-
macht int(teststr) nicht nur den pointer auf dieses array zum int? die werte werden garnicht angesprochen
das sieht doch nach einer cast-variante aus...
-
Char[2] und Integer sind ja beide 2 Byte lang. Warum kommt net des raus, was eigentlich rauskommen sollt, wenn ich per int() auf den Char[2] zugreif?
-
the_MUKe schrieb:
Char[2] und Integer sind ja beide 2 Byte lang.
Was ist los?
the_MUKe schrieb:
Warum kommt net des raus, was eigentlich rauskommen sollt, wenn ich per int() auf den Char[2] zugreif?
Wenn du C/C++ programmierst, solltest du schon wissen was du machst. Und nicht einfach coden und dann hoffen, dass es so funktioniert wie du willst.
-
ein int ist 32 bit / 4 byte lang.
ein char ist 8 bit / 1 byte lang.
(diese infos sind für ihn ausreichend).wenn du ein feld/array anlegst, z.b. char meinfeld[2], dann wird im arbeitsspeicher 2 mal 1 byte reserviert und meinfeld (eigentlich ist es ein pointer) zeigt dann auf den ersten reservierten char im speicher.
meinfeld ist an sich ein int (also 4 byte), ist aber vom typ her ein pointer (zeiger) auf char.
in c sind arrays und pointer technisch das gleiche.
mit *meinfeld kannst du auf meinfeld[0] (das erste element) zugreifen.
meinfeld enthält nur einen pointer, mit dem du als mensch nichts anfangen kannst.
wenn du beide werte tauschen willst, dann mach folgendes:char zwischenspeicher; zwischenspeicher = meinfeld[0]; meinfeld[0] = meinfeld[1]; meinfeld[1] = zwischenspeicher;
lies dir besser noch einige tutorials zu c (oder auch c++) durch.
-
c.rackwitz schrieb:
ein int ist 32 bit / 4 byte lang.
ein char ist 8 bit / 1 byte lang....auf x86 pc. unter anderen systemen kann's ganz anders sein.
c.rackwitz schrieb:
in c sind arrays und pointer technisch das gleiche.
nö. ein pointer speichert eine adresse. ein array enthält 1...n elemente des gleichen typs
-
c.rackwitz schrieb:
und meinfeld (eigentlich ist es ein pointer)
Nein, eigentlich nicht. Es ist aber möglich, eine Array nach Pointer Umwandlung durchzuführen. Array Variablen werden wie Compilezeitadressen behandelt, Zeiger hingegen enthalten laufzeitabhängige Adressen.
-
@net:
c.rackwitz schrieb:
(diese infos sind für ihn ausreichend).
verstehst du mich? er muss solche details nicht wissen, er hat schon genug zu verstehen.
net schrieb:
ein pointer speichert eine adresse. ein array enthält 1...n elemente des gleichen typs
damit hast du recht, aber dein "nö" ist noch lange nicht gerechtfertigt. schon mal was von "pointer-array-dualität" gehört? wenn ich falsch liegen würde, dann wäre zeigerarithmetik fürn arsch und *meinfeld wäre ein fehler
@groovemaster:
meinfeld ist ein pointer oder array. es gilt das gleiche, was ich schon weiter oben zu net gesagt habe. array-nach-pointer umwandlung hab ich noch nie gehört. arrays sind pointer, da muss nichts gecastet oder umgewandelt werden. arrays sind allerdings insofern speziell, als dass man sich sicher sein kann, dass hinter dem pointer ein speicherbereich mit aneinanderhängenden variablen gleichen typs liegt, die man mit indizes ansprechen kann (meinfeld[5000] z.b.)du unterscheidest zwischen "compile time" und "run time". das ist insoweit richtig, als dass der compiler optimierungen vornimmt, wenn man statische arrays hat (z.b. char nocheinfeld[100]), allerdings geht diese unterscheidung verloren, wenn man dynamisch arrays will, weil man dann mit pointern arbeitet (char *nocheinfeld; nocheinfeld = new char[101]).
-
c.rackwitz schrieb:
...aber dein "nö" ist noch lange nicht gerechtfertigt. schon mal was von "pointer-array-dualität" gehört?
du meinst sowas...
int a[100]; int *b = a; char *p = "lala"; // oder sowas
weil man einem pointer die adresse eines arrays zuweisen kann?
ja, das ist aber eine spezialität von c. dein post erweckte den eindruck, als seien pointer und arrays dasselbe. denn...char a[100]; // nur 100 chars, es gibt keinen pointer 'a' a = (char*)0; // geht nicht char *p = "huch"; // aber hier - 5 chars und ein char-pointer p = (char*)0; // geht
-
net schrieb:
char a[100]; // nur 100 chars, es gibt keinen pointer 'a' a = (char*)0; // geht nicht char *p = "huch"; // aber hier - 5 chars und ein char-pointer p = (char*)0; // geht
stimmt. man kann arrays auch als konstante pointer ansehen. zuweisung wird durch das typensystem verhindert. macht auch sinn, wenn man sich z.b. vorstellen kann, dass das programm ein a=malloc(100) ausführt, um die 100 chars zu bekommen und ein free(a) am ende ausführt (theoretisch, weiß nicht, wie es wirklich ist).
char a[100]; char b[100]; a = b; bei C: test.c:6: incompatible types in assignment bei C++: test.cpp:6: ISO C++ forbids assignment of arrays
-
c.rackwitz schrieb:
char a[100]; char b[100]; a = b; bei C: test.c:6: incompatible types in assignment bei C++: test.cpp:6: ISO C++ forbids assignment of arrays
die c++ fehlermeldung gefällt mir aber besser
so wie es aussieht versucht 'c' dem array a die adresse von b zuzuweisen während 'c++' versucht, dem array a ein array b zuzuweisen.
-
c.rackwitz schrieb:
meinfeld ist ein pointer oder array. es gilt das gleiche, was ich schon weiter oben zu net gesagt habe. array-nach-pointer umwandlung hab ich noch nie gehört. arrays sind pointer
Ich hoffe, du hast mittlerweile mitbekommen, dass dem nicht so ist. Wenn du mehr Infos brauchst, dann schau dir mal im Standard Abschnitt 6.3.2.1 und 6.5.2.1 an.
-
groovemaster schrieb:
c.rackwitz schrieb:
meinfeld ist ein pointer oder array. es gilt das gleiche, was ich schon weiter oben zu net gesagt habe. array-nach-pointer umwandlung hab ich noch nie gehört. arrays sind pointer
Ich hoffe, du hast mittlerweile mitbekommen, dass dem nicht so ist. Wenn du mehr Infos brauchst, dann schau dir mal im Standard Abschnitt 6.3.2.1 und 6.5.2.1 an.
In den genannten Abschnitten des C Standards ISO/IEC 9899:1999 wird unterschieden zwischen den Typen array und pointer. Jedoch werden arrays im Gebrauch häufig in pointer umgewandelt. Diese implizite Umwandlung und "Verwandtschaft" meinte ich, wenn ich "array ist pointer" gesagt habe.
Ich möchte auch nicht verleugnen, dass arrays und pointer vom Typ etwas unterschiedliches sind. Sie sind aber dennoch verwandt. sizeof() unterscheidet ja z.B. auch zwischen pointern und arrays (war mir vorher nicht klar).Ausschnitt aus dem o.g. Standard, 6.5.2.1 (4) EXAMPLE
Consider the array object defined by the declaration
int x[3][5];
Here x is a 3 x 5 array of ints; more precisely, x is an array of three element objects, each of which is an
array of five ints. In the expression x[i], which is equivalent to (*((x)+(i))), x is first converted to
a pointer to the initial array of five ints. Then i is adjusted according to the type of x, which conceptually
entails multiplying i by the size of the object to which the pointer points, namely an array of five int
objects. The results are added and indirection is applied to yield an array of five ints. When used in the
expression x[i][j], that array is in turn converted to a pointer to the first of the ints, so x[i][j]
yields an int.[edit1] Ich weiß, die Papiere zum Standard kosten "nur" 18 Dollar (oder Euro?). Nur will sich nicht jeder sowas leisten... reines Glück, dass ich zu den Dokumenten Zugang habe.
Korrigiert mich, wenn ich was Falsches gelesen habe
-
Für den C++ Standard gibts 'ne Online Version, würde mich nicht wundern, wenn's sowas auch für C gibt.