amiga-news DEUTSCHE VERSION
.
Links| Forums| Comments| Report news
.
Chat| Polls| Newsticker| Archive
.

amiga-news.de Forum > Programmierung > 4-Byte char => int? [ - Search - New posts - Register - Login - ]

-1- [ - Post reply - ]

2008-08-29, 12:23 h

Der_Wanderer
Posts: 1229
User
Hallo!

In Amiblitz kann man einen 4 Byte grossen String
wie ein 32bit Integer benutzen.

Z.B. so:

If header=@"FORM" Then ...

was sehr praktisch ist. Vor allem in C wäre sowas praktisch,
wo die String Handhabung etwas umständlicher ist.
Daher meine Frage: Gibt es soetwas in C, oder kann jemand ein Macro posten das sowas ähnliches macht?

Konket lese ich Chunk IDs aus einer Datei, und will sie mit Switch vergleichen.

Also

Switch(header) {
case "FORM" : ...
case "BODY" : ...
case "CMAP" : ...
}

so in der Art.

Danke schonmal!

--
Thilo Köhler, Author von:
HD-Rec, Sweeper, Samplemanager, ArTKanoid, Monkeyscript, Toadies, AsteroidsTR, TuiTED, PosTED, TKPlayer, AudioConverter, ScreenCam, PerlinFX, MapEdit, TK AB3 Includes und viele mehr...
Homepage: http://www.hd-rec.de


[ - Answer - Quote - Direct link - ]

2008-08-29, 12:47 h

thomas
Posts: 7718
User
@Der_Wanderer:

code:
#define MAKE_ID(a,b,c,d)  (((a) << 24) | ((b) << 16) | ((c) << 8) | (d))

#define ID_FORM MAKE_ID('F','O','R','M')

if (header == ID_FORM)
{
...
}



Siehe auch libraries/iffparse.h und datatypes/#?class.h.

Gruß Thomas

--
Email: thomas-rapp@web.de
Home: thomas-rapp.homepage.t-online.de/

[ Dieser Beitrag wurde von thomas am 29.08.2008 um 12:48 Uhr geändert. ]

[ - Answer - Quote - Direct link - ]

2008-08-29, 12:53 h

DrNOP
Posts: 4118
User
Also ich würde das Lesen und das Auswerten der Datei sowieso trennen.

Und für dein konkretes Problem würde ich so ansetzen:

- Ein enum machen mit den Parametern, die du erwartest
code:
/* file parameter info */
typedef enum
{
	PRM_FORM, PRM_BODY, PRM_CMAP
} FILEPRMSTATE;


- gleich beim Lesen der Datei einen string compare machen und damit eine passende Variable setzen
code:
if (!strcmp(pc_name,"FORM"))
{
	header = PRM_FORM;
}
else
{
	...


- mit dieser Variablen dann den Switch aufbauen:
code:
Switch(header)
{
	case PRM_FORM : ...
	case PRM_BODY : ...
	case PRM_CMAP : ...
}

--
Signaturen mit mehr als zwei Zeilen gehen mir auf den Wecker

[ - Answer - Quote - Direct link - ]

2008-08-29, 13:01 h

tokai
Posts: 1071
User
FORM, BODY, CMAP? :) Klingt nach Parsen von IFF-Dateien. ;)

Kleiner Tipp: anstatt das selbst zu machen, kann man einfach iffparse.library verwenden. Beispiele diesbzgl. sollten im NDK zu finden sein.


regards,
tokai
--
http://www.christianrosentreter.com ~ MorphOS Software

[ - Answer - Quote - Direct link - ]

2008-08-29, 13:03 h

Holger
Posts: 8116
User
Zitat:
Original von DrNOP:
- gleich beim Lesen der Datei einen string compare machen und damit eine passende Variable setzen

Kennst Du den Unterschied zwischen einem C-String und einem char-Array? Das kleine aber feine 0-byte, dass bei einer 4 byte-ID nicht vorhanden ist...

Wie thomas schon sagte, gibt's das richtige schon in einer header Datei. Nebenbei gesagt, macht die Library, für die der header gedacht ist, auch schon das Parsen einer aus Chunks bestehenden Datei.

mfg

--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Answer - Quote - Direct link - ]

2008-08-29, 13:05 h

Der_Wanderer
Posts: 1229
User
Das mit dem IFF-Header war nur ein Beispiel.
Es geht nicht um eine IFF Datei, sondern um ein eigenes Dateiformat mit "tagged" Daten, d.h. Die Datei ist so aufgebaut:

code:
char[4] tagID
int tagValue
char[4] tagID
int tagValue
...

etc.

Bisher mache ich das so:
code:
#define int4(A,B,C,D) (int)(A|B<<8|C<<16|D<<24)

...
switch(tagID) {
  case int4('T','Y','P','E') : type   = tagValue; break;
  case int4('W','D','T','H') : width  = tagValue; break;
  case int4('H','I','G','H') : height = tagValue; break;
  ...
}

Aber ich würde gerne die vielen ',' loswerden.
In Amiblitz sähe das so aus:
code:
Select(tagID)
  case @"TYPE" : type   = tagValue
  case @"WDTH" : width  = tagValue
  case @"HIGH" : height = tagValue
  ...
End Select


Sinn eines solchen Dateiformates ist es, dass es leicht Erweitert oder Reduziert werden kann ohne Kompatibelität zu verlieren, ähnlich wie XML oder HTML, aber mit weniger Speicheraufwand und schnellerem parsen. Ausserdem lässt sich so eine Datei leicht in einem Hex Editor modifizieren, ohne dass man sie Struktur kennen muss.




--
Thilo Köhler, Author von:
HD-Rec, Sweeper, Samplemanager, ArTKanoid, Monkeyscript, Toadies, AsteroidsTR, TuiTED, PosTED, TKPlayer, AudioConverter, ScreenCam, PerlinFX, MapEdit, TK AB3 Includes und viele mehr...
Homepage: http://www.hd-rec.de



[ Dieser Beitrag wurde von Der_Wanderer am 29.08.2008 um 13:08 Uhr geändert. ]

[ - Answer - Quote - Direct link - ]

2008-08-29, 13:11 h

thomas
Posts: 7718
User
@Der_Wanderer:

Habe ich doch vorgemacht:

code:
#define int4(A,B,C,D) (int)(A|B<<8|C<<16|D<<24)
#define TYPE int4('T','Y','P','E')
#define WDTH int4('W','D','T','H')
#define HIGH int4('H','I','H','H')

...
switch(tagID) {
case TYPE : type = tagValue; break;
case WDTH : width = tagValue; break;
case HIGH : height = tagValue; break;
...
}


Gruß Thomas

--
Email: thomas-rapp@web.de
Home: thomas-rapp.homepage.t-online.de/

[ - Answer - Quote - Direct link - ]

2008-08-29, 13:14 h

Der_Wanderer
Posts: 1229
User
@thomas:
Hm, das ist aber nicht wirklich kürzer sonder länger, und ich hab das ',' Gewurschtel nur nach oben verschoben, wo es noch undurchsichtiger wird, z.B. wenn dort ein Schreibfehler passiert und ich mich beim Betrachten der Zeile "case TYPE" wundere, warum das nicht funzt.

--
Thilo Köhler, Author von:
HD-Rec, Sweeper, Samplemanager, ArTKanoid, Monkeyscript, Toadies, AsteroidsTR, TuiTED, PosTED, TKPlayer, AudioConverter, ScreenCam, PerlinFX, MapEdit, TK AB3 Includes und viele mehr...
Homepage: http://www.hd-rec.de


[ - Answer - Quote - Direct link - ]

2008-08-29, 13:14 h

thomas
Posts: 7718
User

Noch etwas wichtiges:

Zitat:
(A|B<<8|C<<16|D<<24)

Das haut so nicht hin. | hat eine höhere Priorität als <<. Du mußt die << in Klammern stellen. Und die Argumente von Makros sollte man sowieso in Klammern schreiben, sonst erlebt man manchmal sein blaues Wunder.

Gruß Thomas

--
Email: thomas-rapp@web.de
Home: thomas-rapp.homepage.t-online.de/

[ - Answer - Quote - Direct link - ]

2008-08-29, 13:47 h

Der_Wanderer
Posts: 1229
User
@thomas:
Danke für den Hinweis.
--
Thilo Köhler, Author von:
HD-Rec, Sweeper, Samplemanager, ArTKanoid, Monkeyscript, Toadies, AsteroidsTR, TuiTED, PosTED, TKPlayer, AudioConverter, ScreenCam, PerlinFX, MapEdit, TK AB3 Includes und viele mehr...
Homepage: http://www.hd-rec.de


[ - Answer - Quote - Direct link - ]

2008-08-29, 14:07 h

Holger
Posts: 8116
User
@Der_Wanderer:
Einige C-Compiler erlauben die Angabe eines char-Literals mit mehreren bytes. Also ala
code:
switch(id)
{
  case 'FORM': ... break;
  case 'BODY': ... break;
}

Aber ich würde die Finger davon lassen, und beim Makro-Stil bleiben. IDs, die man genau einmal definiert, sind nicht so fehleranfällig. Und wenn man sich vertippt, werden trotzdem konsistenterweise die gleichen Werte für das Lesen und Schreiben verwendet, somit funktioniert der Code. Man wundert sich nur dann, wenn man die Datei wirklich mit nem Hex-Editor bearbeiten will.

mfg

--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Answer - Quote - Direct link - ]

2008-08-29, 16:07 h

DrNOP
Posts: 4118
User
Zitat:
Original von Holger:
Zitat:
Original von DrNOP:
- gleich beim Lesen der Datei einen string compare machen und damit eine passende Variable setzen

Kennst Du den Unterschied zwischen einem C-String und einem char-Array? Das kleine aber feine 0-byte, dass bei einer 4 byte-ID nicht vorhanden ist...
Äh, ja, kenn ich. Nur spricht der einleitende Beitrag von Strings. Genauer gesagt läßt er sich nicht über die Endekennung aus. Wenn also kein 0-Byte am Ende vorhanden ist kann er immer noch strncmp statt strcmp benutzen. Und ich verstehe nicht, warum du mir daraus einen Strick drehen willst.

Zitat:
Original von Der_Wanderer:
Das mit dem IFF-Header war nur ein Beispiel.
Es geht nicht um eine IFF Datei, sondern um ein eigenes Dateiformat mit "tagged" Daten, d.h. Die Datei ist so aufgebaut:

code:
char[4] tagID
int tagValue
char[4] tagID
int tagValue
...

etc.

Wieso nimmst du für sowas nicht gleich XML? Kannst expat zum Parsen nehmen und bist fast fertig. ;)
--
Signaturen mit mehr als zwei Zeilen gehen mir auf den Wecker

[ - Answer - Quote - Direct link - ]

2008-08-29, 16:24 h

Holger
Posts: 8116
User
Zitat:
Original von DrNOP:
Äh, ja, kenn ich. Nur spricht der einleitende Beitrag von Strings. Genauer gesagt läßt er sich nicht über die Endekennung aus.

Er spricht von 4 byte großen Strings, die wie 32 Bit-Integer behandelt werden (können). Und thomas hatte schon die passende Antwort gegeben.

Wie auch immer, ich entschuldige mich für die unfreundliche Formulierung meiner Antwort. Ich will Dir keinesfalls irgendwelche Stricke drehen...

mfg

--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Answer - Quote - Direct link - ]

2008-08-29, 17:14 h

Der_Wanderer
Posts: 1229
User
Ok, das war für reinrassige C-Progger wohl etwas zu schwammig formuliert.

Eigentlich suche ich eine Möglichkeit, 32bit Zahlen im base256 Format anzugeben. Also analog zum base16(Hex) oder bin:

int a = 0b1010101010101011111011011110111;
int b = 0xDEADBEEF;
int c = 0cRind;

0c stehe jetzt mal für base256.
In AB3 verwende ich das häufig für Tags oder andere Identifier, z.B.

image_Save{0,"myfile.jpg",@"JPEG"}
ahi_SaveSound{0,"myfile.mp3",@"MP3"}


--
Thilo Köhler, Author von:
HD-Rec, Sweeper, Samplemanager, ArTKanoid, Monkeyscript, Toadies, AsteroidsTR, TuiTED, PosTED, TKPlayer, AudioConverter, ScreenCam, PerlinFX, MapEdit, TK AB3 Includes und viele mehr...
Homepage: http://www.hd-rec.de


[ - Answer - Quote - Direct link - ]

2008-08-29, 17:27 h

thomas
Posts: 7718
User
@Der_Wanderer:


Und was ist so falsch an

int c = ID_RIND;

?

(Eigentlich mußt du unsigned long nehmen, denn int ist nicht zwingend 32 Bit, deshalb long und Zeichen können durchaus größer als 128 sein, deshalb unsigned.)


Oder an

image_Save(0,"myfile.jpg",ID_JPEG};
ahi_SaveSound(0,"myfile.mp3",ID_MP3);

?

Gruß Thomas

--
Email: thomas-rapp@web.de
Home: thomas-rapp.homepage.t-online.de/

[ - Answer - Quote - Direct link - ]

2008-08-29, 18:53 h

ZeroG
Posts: 1487
User
@Der_Wanderer:
Ich würde es persönlich so machen wie Thomas und die ganzen #defines in einem extra Header unterbringen, aber vielleicht gefällt dir das besser.
code:
#include <proto/exec.h>
#include <stdio.h>

#define getID(x) (*(uint32 *)(&x))

void main()
{
    printf("%s = %lXn", "LIST", getID("LIST"));
}


[ - Answer - Quote - Direct link - ]

2008-08-29, 19:49 h

woop
Posts: 67
User
Bitte auch daran denken, dass in einem Datenstrom oder in einem String die Zeichen 'FORM' auch an nicht durch vier teilbaren oder an ungeraden Adressen stehen könnten. Da kann dann ein einfacher 68000er nicht mehr als long darauf zugreifen.

[ - Answer - Quote - Direct link - ]

2008-08-29, 19:51 h

thomas
Posts: 7718
User
@ZeroG:

Das geht aber nicht mit case. Da sind nur Konstanten erlaubt.

Gruß Thomas

--
Email: thomas-rapp@web.de
Home: thomas-rapp.homepage.t-online.de/

[ - Answer - Quote - Direct link - ]

2008-08-29, 19:54 h

thomas
Posts: 7718
User
@woop:

Das kommt auf das Dateiformat an. Bei IFF z.B. kann das nicht passieren, weil bei ungeraden Längen immer ein Füllbyte eingefügt wird.

Wenn man sich das Dateiformat selbst ausdenkt, kann man darauf achten.

Gruß Thomas

--
Email: thomas-rapp@web.de
Home: thomas-rapp.homepage.t-online.de/

[ - Answer - Quote - Direct link - ]

2008-08-29, 20:20 h

woop
Posts: 67
User
@thomas:

Das ist mir schon klar, dass IFF dahingehend designed wurde, dass sowas nicht vorkommt, aber OT meint ja, es würde eben nicht um IFF sondern um was eigenes gehen, daher mein Hinweis.

[ - Answer - Quote - Direct link - ]

2008-08-29, 21:00 h

bruZard
Posts: 307
User
Watn Scheiss .. warum interpretierst Du den Kram nicht gleich in AB, dann bleibt Dir der Steinzeit Kram aus C erspart.
In AB ist ein String ein String ist ein String ... Wenn Du das Format auch noch selber erfindest ist es doch Banane was ein C-Neanderthaler damit macht. Lies einfach einen String ein (die Länge kennst Du ja wohl) und vergleiche ihn ... weint keiner, ist immer eindeutig.

--
Methusalem Kino - Das Blog über Nichts und Alles.

[ - Answer - Quote - Direct link - ]

2008-08-29, 21:34 h

Der_Wanderer
Posts: 1229
User
Es geht nicht um IFF. Und ich weiss auch, dass man sích vorher eine Konstante erstellen kann.
Ich dacht nur, es gibt eine einfache Möglichkeit eine Zahl zu erstellen mit Basis 256.
Im Idealfall sind da gar keine Strings oder Character Arrays involviert. Wie bei AB3 eben, da ist @"TEST" eine 32bit integer Zahl, kein String und auch kein Char Array, signed oder unsigned spielt keine Rolle, erst wenn man hinterher damit rechnen will.

Eben so:

0xDEADBEEF
0cRIND

das wäre ideal. Ok, gibts nicht, muss ich halt anders machen. Man muss an das Thema aber nicht gleich so emotional rangehen, oder?
Wenn ich das Programm in AB3 scheiben könnte, müsste ich ja hier nicht nach C fragen.

Es geht um ein Program, was in C geschrieben werden muss.
Ich habe jetzt den Ratschalg befoglt, und Konstanten definiert. Hat natürlich auch seinen Vorteil, dass bei der Load und bei der Save Routine Schreibfehler ausgeschlossen sind. Danke an euch alle!

--
Thilo Köhler, Author von:
HD-Rec, Sweeper, Samplemanager, ArTKanoid, Monkeyscript, Toadies, AsteroidsTR, TuiTED, PosTED, TKPlayer, AudioConverter, ScreenCam, PerlinFX, MapEdit, TK AB3 Includes und viele mehr...
Homepage: http://www.hd-rec.de



[ Dieser Beitrag wurde von Der_Wanderer am 29.08.2008 um 22:02 Uhr geändert. ]

[ - Answer - Quote - Direct link - ]

2008-08-29, 23:39 h

ZeroG
Posts: 1487
User
@thomas:
Zitat:
Das geht aber nicht mit case. Da sind nur Konstanten erlaubt.
Ups. Stimmt.

[ - Answer - Quote - Direct link - ]

2008-09-01, 11:53 h

Holger
Posts: 8116
User
Zitat:
Original von thomas:
(Eigentlich mußt du unsigned long nehmen, denn int ist nicht zwingend 32 Bit, deshalb long und Zeichen können durchaus größer als 128 sein, deshalb unsigned.)

long ist auch nicht zwingend 32 Bit.
Und ob die Werte signed oder unsigned interpretiert werden, hat für IDs, mit denen niemals gerechnet oder ein größer-als/kleiner-als Vergleich stattfindet, überhaupt keine Bedeutung.
Zitat:
Original von Der_Wanderer:
Ich dacht nur, es gibt eine einfache Möglichkeit eine Zahl zu erstellen mit Basis 256.

Basis 256 tss, tss.
C mit Zeichen größer als 128 zu benutzen, wäre mehr als übermütig. Die Erfinder von C waren sogar besorgt, dass unter den damals verbreiteten Rechnern welche sein könnten, die mit den "Sonderzeichen" wie eckigen und geschweiften Klammern von C überfordert sein könnten.

Weswegen die tollen Trigraphen erfunden wurden.
??( heißt eckige Klammer auf, ??) eckige Klammer zu, ??< ??> macht selbiges mit geschweiften Klammern.

Die hätten bestimmt damit gerechnet, dass es auch Rechner geben könnte, bei denen eine vier-Zeichen Sequenz in zwei byte passen könnte. Heute musst Du damit Rechnern, dass sie 8 bytes benötigt.

"C ist portabel" :lach:
Zitat:
Ok, gibts nicht, muss ich halt anders machen.
Wie schon gesagt, gibt es bei einigen Compilern, aber nicht im Standard.

mfg

--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Answer - Quote - Direct link - ]

2008-09-01, 12:17 h

Der_Wanderer
Posts: 1229
User
Basis256 heisst ja nicht, dass ich für die IDs Zeichen>127 benutzen muss. Aber ich verstehe schon das Dilemma.
Habe mich jetzt mit der #define Variante angefreundet.

--
Thilo Köhler, Author von:
HD-Rec, Sweeper, Samplemanager, ArTKanoid, Monkeyscript, Toadies, AsteroidsTR, TuiTED, PosTED, TKPlayer, AudioConverter, ScreenCam, PerlinFX, MapEdit, TK AB3 Includes und viele mehr...
Homepage: http://www.hd-rec.de


[ - Answer - Quote - Direct link - ]


-1- [ - Post reply - ]


amiga-news.de Forum > Programmierung > 4-Byte char => int? [ - Search - New posts - Register - Login - ]


.
Masthead | Privacy policy | Netiquette | Advertising | Contact
Copyright © 1998-2024 by amiga-news.de - all rights reserved.
.