Waiting for answer This question has not been answered yet. You can hire a professional tutor to get the answer.

QUESTION

Lab 6: File I/O external data representation; fopen(), fclose(), fread() and fwrite(); struct practice Goals After this lab you will be able to...

A less-used fifth operation, SEEK(), allows you to set the read/write position directly without reading or writing.

Almost every programming language supports a version of this interface. You may recognize it from Python. For the C programmer, this interface is provided by these four system calls defined in stdio.h:

FILE * fopen( const char * filename, const char * mode);size_t fwrite( const void * ptr, size_t size, size_t nitems, FILE * stream);size_t fread( void * ptr,size_t size, size_t nitems, FILE * stream);int fclose( FILE *stream);Useful extras

You may find these useful:

  • fseek() : repositions the current read/write location.
  • feof() : tells you if the end-of-file is reached.
  • ftell() : returns the current read/write location.
  • ftruncate() : truncate a file to a specified length.
  • stat() : get file status
Files by example

Examples of using the file API as demonstrated in class, and beyond. Background on files and links to the interface specifications are provided below.

Write a simple array to a file#include <stdio.h>int main( int argc, char* argv[] ){ const size_t len = 100; int arr[len]; // put data in the array // ... // write the array into a file (error checks ommitted) FILE* f = fopen( "myfile", "w" ); fwrite( arr, sizeof(int), len, f ); fclose( f ); return 0;}Read a simple array from a file#include <stdio.h>int main( int argc, char* argv[] ){ const size_t len = 100; int arr[len]; // read the array from a file (error checks ommitted) FILE* f = fopen( "myfile", "r" ); fread( arr, sizeof(int), len, f ); fclose( f ); // use the array // ... return 0;}Write an array of structs to a file, then read it back#include <stdio.h>#include <stdlib.h>#include <string.h>typedef struct { int x,y,z;} point3d_t;int main( int argc, char* argv[] ){ const size_t len = atoi(argv[1]); // array of points to write out point3d_t wpts[len]; // fill with random points for( size_t i=0; i<len; i++ ){wpts[i].x = rand() % 100;wpts[i].y = rand() % 100;wpts[i].z = rand() % 100;} // write the struct to a file (error checks ommitted) FILE* f1 = fopen( argv[2], "w" ); fwrite( wpts, sizeof(point3d_t), len, f1 ); fclose( f1 ); // array of points to read in from the same file point3d_t rpts[len]; // read the array from a file (error checks ommitted) FILE* f2 = fopen( argv[2], "r" ); fread( rpts, sizeof(point3d_t), len, f2 ); fclose( f2 ); if( memcmp( wpts, rpts, len * sizeof(rpts[0]) ) != 0 )puts( "Arrays differ" ); elseputs( "Arrays match" ); return 0;}Saving and loading an image structure, with error checking

This example shows the use of a simple file format that uses a short "header" to describe the file contents, so that an object of unknown size can be loaded.

Make sure you understand this example in detail. It combines elements from the examples above into a simple but realistic implementation of a file format.

/* saves an image to the filesytem using the file format:[ cols | rows | pixels ]where:cols is a uint32_t indicating image widthrows is a uint32_t indicating image heightpixels is cols * rows of uint8_ts indicating pixel grey levels*/int img_save( const img_t* img, const char* filename ){ assert( img ); assert( img->data ); FILE* f = fopen( filename, "w" ); if( f == NULL ){puts( "Failed to open image file for writing" );return 1;} // write the image dimensions header uint32_t hdr[2]; hdr[0] = img->cols; hdr[1] = img->rows; if( fwrite( hdr, sizeof(uint32_t), 2, f ) != 2 ){puts( "Failed to write image header" );return 2; const size_t len = img->cols * img->rows; if( fwrite( img->data, sizeof(uint8_t), len, f ) != len ){puts( "Failed to write image pixels" );return 3; fclose( f ); return 0;}/* loads an img_t from the filesystem using the same format as img_save().Warning: any existing pixel data in img->data is not free()d.*/int img_load( img_t* img, const char* filename ){ assert( img ); FILE* f = fopen( filename, "r" ); if( f == NULL ){puts( "Failed to open image file for reading" );return 1;} // read the image dimensions header: uint32_t hdr[2]; if( fread( hdr, sizeof(uint32_t), 2, f ) != 2 ){puts( "Failed to read image header" );return 2; img->cols = hdr[0]; img->rows = hdr[1]; // helpful debug: // printf( "read header: %u cols %u rowsn", // img->cols, img->rows ); // allocate array for pixels now we know the size const size_t len = img->cols * img->rows; img->data = malloc( len * sizeof(uint8_t) ); assert( img->data ); // read pixel data into the pixel array if( fread( img->data, sizeof(uint8_t), len, f ) != len ) { puts( "Failed to read image pixels" ); return 3; fclose( f ); return 0;}

Usage:

img_t img;img_load( &img, "before.img" );image_frobinate( img ); // manipulate the image somehowimg_save( &img, "after.img" );Task 1: Serialize an array of integers to a binary-format file

Extend the functionality of your integer array from Lab 5 to support saving and loading arrays from the filesystem in a binary format.

Fetch the header file "intarr.h". It contains these new function declarations:

/* LAB 6 TASK 1 *//* Save the entire array ia into a file called 'filename' in a binary file format that can be loaded by intarr_load_binary(). Returns zero on success, or a non-zero error code on failure. Arrays of length 0 should produce an output file containing an empty array.*/int intarr_save_binary( intarr_t* ia, const char* filename );/* Load a new array from the file called 'filename', that was previously saved using intarr_save_binary(). Returns a pointer to a newly-allocated intarr_t on success, or NULL on failure.*/intarr_t* intarr_load_binary( const char* filename );/* LAB 6 TASK 2 *//* Save the entire array ia into a file called 'filename' in a JSON text file array file format that can be loaded by intarr_load_json(). Returns zero on success, or a non-zero error code on failure. Arrays of length 0 should produce an output file containing an empty array. The JSON output should be human-readable. Examples: The following line is a valid JSON array: [ 100, 200, 300 ] The following lines are a valid JSON array: [ 100, 200, 300 ]*/int intarr_save_json( intarr_t* ia, const char* filename );/* Load a new array from the file called 'filename', that was previously saved using intarr_save(). The file may contain an array of length 0. Returns a pointer to a newly-allocated intarr_t on success (even if that array has length 0), or NULL on failure.*/intarr_t* intarr_load_json( const char* filename );Submission

Commit the single file "t2.c" to your repo in the lab 6 directory.

Show more
LEARN MORE EFFECTIVELY AND GET BETTER GRADES!
Ask a Question