Advertisement
Guest User

Untitled

a guest
Feb 20th, 2018
65
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.81 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <assert.h>
  3.  
  4. #define TILES_WIDTH 64
  5. #define TILES_HEIGHT 32
  6. #define TILES_MAGIC 0xFEEDBEEF
  7.  
  8. typedef enum { } tiletype_t;
  9.  
  10. typedef struct
  11. {
  12.     int magic;
  13.     int tileswidth;
  14.     int tilesheight;
  15. } tileheader_t;
  16.  
  17. /* Dessa funktioner visar en simpel abstraktion för fwrite/fread.
  18.  * Gör att man inte råkar göra fel på utskrift.
  19.  * Har inte använt dessa i koden då jag anser det överflödigt men kanske hjälper dig.
  20.  * 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).
  21.  * 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. */
  22. inline void fwrite_b(const void *data, size_t nbytes, FILE *stream)
  23. {
  24.     size_t written = fwrite(data, 1, nbytes, stream);
  25.     assert(written == nbytes);
  26. }
  27. inline void fread_b(void *buffer, size_t nbytes, FILE *stream)
  28. {
  29.     size_t read = fread(buffer, 1, nbytes, stream);
  30.     assert(read == nbytes);
  31. }
  32.  
  33. int main(int argc, const char *argv[])
  34. {
  35.     /* Antar att du inte alltid vet storleken men annars: tiletype_t tiles[TILES_WIDTH][TILES_HEIGHT];
  36.      * eller byta plats på dem beroende på minnes layout */
  37.     tiletype_t *tiles = malloc(sizeof(tiletype_t) * TILES_WIDTH * TILES_HEIGHT);
  38.  
  39.     /* Sätt tiles till något meningsfullt */
  40.     for (int i = 0; i < TILES_WIDTH; ++i)
  41.     {
  42.         for (int j = 0; j < TILES_HEIGHT; ++j)
  43.         {
  44.             tiles[i * TILES_WIDTH + j] = 0;
  45.         }
  46.     }
  47.  
  48.     /* Initiera headern */
  49.     tileheader_t header = { TILES_MAGIC, TILES_WIDTH, TILES_HEIGHT };
  50.  
  51.     /* wb - write, binary
  52.      * binary kan ibland fixa problem när implementationen av streamsen
  53.      * försöker tänka på saker som \r\n i windows ska vara 'ett tecken'
  54.      * Rekommenderas att alltid använda b flaggan om du inte vet varför du inte ska ha den.
  55.      * Använder den för text själv alltid och gör egen processering av den binära datan som texten utgör.
  56.      * Har fått många skumma fel utan det över åren. */    
  57.     FILE *savefile = fopen("myfile.tiles", "wb");
  58.  
  59.     /* Skriv hela headern till filen.
  60.      * Parameterna till fwrite kan vara något förvirrande;
  61.      * den andra parametern är storleken för objekten du ska skriva,
  62.      * den tredje parametern är antalet sådana objekt.
  63.      * det värde som fwrite returnerar är antalet OBJEKT skriva
  64.      * baserat på den tredje parametern. Alltså INTE antalet bytes skrivna.
  65.      * Good practice brukar anses att ALLTID ange 1 som objekt storlek, och
  66.      * antalet bytes som ska skrivas i tredje parameter istället för så som funktionen
  67.      * "är tänkt att användas". Exakt varför är oklart men jag tippar på att det beror på
  68.      * att det är en onödig abstraktion då man oftast bryr sig om bytes i C och
  69.      * det faller mer naturligt att all kod jobbar på samma sätt. */
  70.     size_t byteswritten = fwrite(&header, 1, sizeof(header), savefile);
  71.  
  72.     /* Kontrollera att vi skrivit hela headern utan korrumption.
  73.      * (Ja, fwrite skriver inte garanterat allt du ber om.) */
  74.     assert(byteswritten == sizeof(header));
  75.  
  76.     /* Skriv nu alla tilesen till filen;
  77.      * Samma princip här för parametrarna till fwrite.
  78.      * Tänk på att inte ta addressen av tiles, det är redan en pekare.. (Gäller även för statisk array) */
  79.     byteswritten = fwrite(tiles, 1, sizeof(tiletype_t) * TILES_WIDTH * TILES_HEIGHT, savefile);
  80.     assert(byteswritten == sizeof(tiletype_t) * TILES_WIDTH * TILES_HEIGHT, savefile);
  81.  
  82.     /* Stäng filen, och frigör resurser. */
  83.     fclose(savefile);
  84.     free(tiles);
  85.     tiles = NULL;
  86.  
  87.     /* Öppna filen igen, fast för läsning denna gången. */
  88.     FILE *loadfile = fopen("myfile.tiles", "rb");
  89.  
  90.     tileheader_t readheader;
  91.     size_t bytesread = fread(&readheader, 1, sizeof(readheader), loadfile);
  92.  
  93.     /* 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) */
  94.     assert(bytesread == sizeof(readheader));
  95.  
  96.     /* Allokera minne för tilesen enligt vad headern säger vi behöver. */
  97.     tiles = malloc(sizeof(tiletype_t) * readheader.tileswidth * readheader.tilesheight);
  98.  
  99.     /* Samma koncept som tidigare, arbetar på bytenivå.
  100.      * Lägg förslagvis byte uträkningen i en variabel så du inte behöver skriva den två gånger som här. */
  101.     bytesread = fread(tiles, 1, sizeof(tiletype_t) * readheader.tileswidth * readheader.tilesheight, loadfile);
  102.    
  103.     /* Kontrollera att vi fick alla tilesen. */
  104.     assert(bytesread == sizeof(tiletype_t) * readheader.tileswidth * readheader.tilesheight);
  105.  
  106.     /* Vi har nu läst in alla tilesen igen; rensa ut minnet och resurserna. */
  107.     fclose(loadfile);
  108.     free(tiles);
  109.  
  110.  
  111.     return 0;
  112. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement