Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <assert.h>
- #define TILES_WIDTH 64
- #define TILES_HEIGHT 32
- #define TILES_MAGIC 0xFEEDBEEF
- typedef enum { } tiletype_t;
- typedef struct
- {
- int magic;
- int tileswidth;
- int tilesheight;
- } tileheader_t;
- /* Dessa funktioner visar en simpel abstraktion för fwrite/fread.
- * Gör att man inte råkar göra fel på utskrift.
- * Har inte använt dessa i koden då jag anser det överflödigt men kanske hjälper dig.
- * Kan underlätta för debugging också, ifall du lägger in asserts direkt i funktionen(eller gör det hela till en macro bara).
- * På det sättet så upptäcker du om du skriver/läser så mycket data att du behöver en lösning som loopar read/write tills allting är igenom. */
- inline void fwrite_b(const void *data, size_t nbytes, FILE *stream)
- {
- size_t written = fwrite(data, 1, nbytes, stream);
- assert(written == nbytes);
- }
- inline void fread_b(void *buffer, size_t nbytes, FILE *stream)
- {
- size_t read = fread(buffer, 1, nbytes, stream);
- assert(read == nbytes);
- }
- int main(int argc, const char *argv[])
- {
- /* Antar att du inte alltid vet storleken men annars: tiletype_t tiles[TILES_WIDTH][TILES_HEIGHT];
- * eller byta plats på dem beroende på minnes layout */
- tiletype_t *tiles = malloc(sizeof(tiletype_t) * TILES_WIDTH * TILES_HEIGHT);
- /* Sätt tiles till något meningsfullt */
- for (int i = 0; i < TILES_WIDTH; ++i)
- {
- for (int j = 0; j < TILES_HEIGHT; ++j)
- {
- tiles[i * TILES_WIDTH + j] = 0;
- }
- }
- /* Initiera headern */
- tileheader_t header = { TILES_MAGIC, TILES_WIDTH, TILES_HEIGHT };
- /* wb - write, binary
- * binary kan ibland fixa problem när implementationen av streamsen
- * försöker tänka på saker som \r\n i windows ska vara 'ett tecken'
- * Rekommenderas att alltid använda b flaggan om du inte vet varför du inte ska ha den.
- * Använder den för text själv alltid och gör egen processering av den binära datan som texten utgör.
- * Har fått många skumma fel utan det över åren. */
- FILE *savefile = fopen("myfile.tiles", "wb");
- /* Skriv hela headern till filen.
- * Parameterna till fwrite kan vara något förvirrande;
- * den andra parametern är storleken för objekten du ska skriva,
- * den tredje parametern är antalet sådana objekt.
- * det värde som fwrite returnerar är antalet OBJEKT skriva
- * baserat på den tredje parametern. Alltså INTE antalet bytes skrivna.
- * Good practice brukar anses att ALLTID ange 1 som objekt storlek, och
- * antalet bytes som ska skrivas i tredje parameter istället för så som funktionen
- * "är tänkt att användas". Exakt varför är oklart men jag tippar på att det beror på
- * att det är en onödig abstraktion då man oftast bryr sig om bytes i C och
- * det faller mer naturligt att all kod jobbar på samma sätt. */
- size_t byteswritten = fwrite(&header, 1, sizeof(header), savefile);
- /* Kontrollera att vi skrivit hela headern utan korrumption.
- * (Ja, fwrite skriver inte garanterat allt du ber om.) */
- assert(byteswritten == sizeof(header));
- /* Skriv nu alla tilesen till filen;
- * Samma princip här för parametrarna till fwrite.
- * Tänk på att inte ta addressen av tiles, det är redan en pekare.. (Gäller även för statisk array) */
- byteswritten = fwrite(tiles, 1, sizeof(tiletype_t) * TILES_WIDTH * TILES_HEIGHT, savefile);
- assert(byteswritten == sizeof(tiletype_t) * TILES_WIDTH * TILES_HEIGHT, savefile);
- /* Stäng filen, och frigör resurser. */
- fclose(savefile);
- free(tiles);
- tiles = NULL;
- /* Öppna filen igen, fast för läsning denna gången. */
- FILE *loadfile = fopen("myfile.tiles", "rb");
- tileheader_t readheader;
- size_t bytesread = fread(&readheader, 1, sizeof(readheader), loadfile);
- /* Samma princip, fread lovar inte att läsa så mycket som du ber om..(Men i praktiken gör den alltid det för små mängder) */
- assert(bytesread == sizeof(readheader));
- /* Allokera minne för tilesen enligt vad headern säger vi behöver. */
- tiles = malloc(sizeof(tiletype_t) * readheader.tileswidth * readheader.tilesheight);
- /* Samma koncept som tidigare, arbetar på bytenivå.
- * Lägg förslagvis byte uträkningen i en variabel så du inte behöver skriva den två gånger som här. */
- bytesread = fread(tiles, 1, sizeof(tiletype_t) * readheader.tileswidth * readheader.tilesheight, loadfile);
- /* Kontrollera att vi fick alla tilesen. */
- assert(bytesread == sizeof(tiletype_t) * readheader.tileswidth * readheader.tilesheight);
- /* Vi har nu läst in alla tilesen igen; rensa ut minnet och resurserna. */
- fclose(loadfile);
- free(tiles);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement