#include file *fopen(const char *path, const...

29
Files #include <stdio.h> FILE *fopen(const char *path, const char *mode); int fclose(FILE *stream); int fprintf(FILE *stream, const char *format, ...); int fscanf(FILE *stream, const char *format, ...); The mode in fopen() can have the following possible values. r Open text file for reading. The stream is positioned at the beginning of the file. r+ Open for reading and writing. The stream is positioned at the beginning of the file. w Truncate file to zero length or create text file for writing. The stream is positioned at the beginning of the file. w+ Open for reading and writing. The file is created if it does not exist, otherwise it is truncated. The stream is positioned at the beginning of the file. a Open for appending (writing at end of file). The file is created if it does not exist. The stream is positioned at the end of the file. a+ Open for reading and appending (writing at end of file). The file is created if it does not exist. The initial file position for reading is at the beginning of the file, but output is always appended to the end of the file.

Upload: dodien

Post on 14-Apr-2018

229 views

Category:

Documents


3 download

TRANSCRIPT

Page 1: #include  FILE *fopen(const char *path, const …cs.boisestate.edu/~alark/cs253/notes/files_functionpointers.pdfComparison of Text versus Binary Files The following

Files

#include <stdio.h>

FILE *fopen(const char *path, const char *mode);int fclose(FILE *stream);int fprintf(FILE *stream, const char *format, ...);int fscanf(FILE *stream, const char *format, ...);

The mode in fopen() can have the following possible values.

r Open text file for reading. The stream is positioned at the beginningof the file.

r+ Open for reading and writing. The stream is positioned at thebeginning of the file.

w Truncate file to zero length or create text file for writing. The streamis positioned at the beginning of the file.

w+ Open for reading and writing. The file is created if it does not exist,otherwise it is truncated. The stream is positioned at the beginningof the file.

a Open for appending (writing at end of file). The file is created if itdoes not exist. The stream is positioned at the end of the file.

a+ Open for reading and appending (writing at end of file). The file iscreated if it does not exist. The initial file position for reading is atthe beginning of the file, but output is always appended to the end ofthe file.

Page 2: #include  FILE *fopen(const char *path, const …cs.boisestate.edu/~alark/cs253/notes/files_functionpointers.pdfComparison of Text versus Binary Files The following

Text versus Binary Files

I Text files are formatted. Useful for human consumption since they arereadable by humans.

I Binary files are unformatted. They take less space and are faster toread/write. Use the fread() and fwrite() functions in thestandard library for binary I/O.

#include <stdio.h>size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);size_t fwrite (const void *ptr, size_t size, size_t nmemb, FILE *stream);

I See following examples:

I files/generate text.cI files/generate binary.c

Page 3: #include  FILE *fopen(const char *path, const …cs.boisestate.edu/~alark/cs253/notes/files_functionpointers.pdfComparison of Text versus Binary Files The following

Comparison of Text versus Binary FilesThe following example shows two files being generated with the samelogical content: one is a text file and the other is a binary file.

[amit@kohinoor files]: time genbin 10000000 1111

real 0m5.372suser 0m2.980ssys 0m2.390s[amit@kohinoor files]: ls -l data.bin-rw-rw-r-- 1 amit amit 280000000 Oct 8 21:35 data.bin[amit@kohinoor files]: time gentxt 10000000 1111

real 1m8.912suser 0m54.740ssys 0m14.100s[amit@kohinoor files]: ls -l data.txt-rw-rw-r-- 1 amit amit 413386064 Oct 8 21:38 data.txt[amit@kohinoor files]:

The file size was double for text files and the time was about 13times slower!

Page 4: #include  FILE *fopen(const char *path, const …cs.boisestate.edu/~alark/cs253/notes/files_functionpointers.pdfComparison of Text versus Binary Files The following

Example: Writing a Text File/* C-examples/files/generate_text.c */#include <stdio.h>#include <stdlib.h>#include <time.h>

struct record {int key;double value1;double value2;double value3;

};const int MAX_KEY = 1000000;

void generate_file(int n, unsigned int seed, FILE *fout){

int i;struct record *next;

next = (struct record *) malloc(sizeof(struct record));

srandom(seed); /* set starting seed for random num. generator */for (i=0; i<n; i++) {

next->key = random() % MAX_KEY;next->value1 = random()/((double)MAX_KEY);next->value2 = random()/((double)MAX_KEY);next->value3 = random()/((double)MAX_KEY);fprintf(fout, "%d %lf %lf %lf\n", next->key,

next->value1, next->value2, next->value3);}

}

int main(int argc, char **argv){

int n;unsigned int seed;FILE *fout;

if (argc < 2) {fprintf(stderr, "Usage: %s <n> [<seed>]\n", argv[0]);exit(1);

}n = atoi(argv[1]);if (argc == 3) {

seed = atoi(argv[1]);}fout = fopen("data.txt", "w");if (!fout) {

perror("");}

generate_file(n ,seed, fout);

fclose(fout);exit(0);

}

Page 5: #include  FILE *fopen(const char *path, const …cs.boisestate.edu/~alark/cs253/notes/files_functionpointers.pdfComparison of Text versus Binary Files The following

Example: Writing a Binary File/* C-examples/files/generate_binary.c */#include <stdio.h>#include <stdlib.h>#include <time.h>

struct record {int key;double value1;double value2;double value3;

};const int MAX_KEY = 1000000;

void generate_file(int n, unsigned int seed, FILE *fout){

int i;struct record *next;

next = (struct record *) malloc(sizeof(struct record));

srandom(seed); /* set starting seed for random num. generator */for (i=0; i<n; i++) {

next->key = random() % MAX_KEY;next->value1 = random()/((double)MAX_KEY);next->value2 = random()/((double)MAX_KEY);next->value3 = random()/((double)MAX_KEY);fwrite(next, sizeof(struct record), 1, fout);

}}

int main(int argc, char **argv){

int n;unsigned int seed;FILE *fout;

if (argc < 2) {fprintf(stderr, "Usage: %s <n> [<seed>]\n", argv[0]);exit(1);

}n = atoi(argv[1]);if (argc == 3) {

seed = atoi(argv[1]);}fout = fopen("data.bin", "w");if (!fout) {

perror("");}

generate_file(n ,seed, fout);

fclose(fout);exit(0);

}

Page 6: #include  FILE *fopen(const char *path, const …cs.boisestate.edu/~alark/cs253/notes/files_functionpointers.pdfComparison of Text versus Binary Files The following

File Random Access

I If a file is stored on a media that supports random access, then wecan seek to anywhere on the file and read/write instead ofreading/writing sequentially.

I Random access files can be text or binary although they are usuallybinary.

I Databases often use random access files for storing data that is sortedor hashed for fast access.

I The main example that we will consider is an binary search programthat reads records from a random access binary file to search for arecord with a matching key value. The data file consists of n records.So the binary search would take O(lg n) disk reads versus O(n) diskreads for sequential access in the worst case.

Page 7: #include  FILE *fopen(const char *path, const …cs.boisestate.edu/~alark/cs253/notes/files_functionpointers.pdfComparison of Text versus Binary Files The following

File Random Access

#include <stdio.h>

int fseek(FILE *stream, long offset, int whence);long ftell(FILE *stream);void rewind(FILE *stream);int fgetpos(FILE *stream, fpos_t *pos);int fsetpos(FILE *stream, fpos_t *pos);

I The fseek function sets the file position indicator for the streampointed to by stream. The new position, measured in bytes, isobtained by adding offset bytes to the position specified by whence. Ifwhence is set to SEEK SET, SEEK CUR, or SEEK END, the offset isrelative to the start of the file, the current position indicator, orend-of-file, respectively. A successful call to the fseek function clearsthe end-of-file indicator for the stream.

I The ftell function obtains the current value of the file positionindicator for the stream pointed to by stream.

I The fgetpos and fsetpos functions are alternate interfaces equivalentto ftell and fseek (with whence set to SEEK SET), setting and storingthe current value of the file offset into or from the object referencedby pos

Page 8: #include  FILE *fopen(const char *path, const …cs.boisestate.edu/~alark/cs253/notes/files_functionpointers.pdfComparison of Text versus Binary Files The following

Example: Determining File Size

/* C-examples/files/filesize.c */#include <stdio.h>#include <stdlib.h>

int main(int argc, char **argv){

long int size;FILE *fin;

if (argc !=2 ) {fprintf(stderr, "Usage: %s <filename>\n", argv[0]);exit(1);

}

fin = fopen(argv[1], "r");if (!fin) {

perror("filesize:");}fseek(fin, 0, SEEK_END);size = ftell(fin);printf("Size of the file %s = %ld bytes\n", argv[1], size);exit(0);

}

Page 9: #include  FILE *fopen(const char *path, const …cs.boisestate.edu/~alark/cs253/notes/files_functionpointers.pdfComparison of Text versus Binary Files The following

Example: External Binary Search

[amit@kohinoor C-examples]$ ls C-examples/files/disk_binary_search/common.h ExternalBinarySearch.c Makefile Record.h timing.cdata.bin ExternalBinarySearch.h Record.c test_bsearch.c

Page 10: #include  FILE *fopen(const char *path, const …cs.boisestate.edu/~alark/cs253/notes/files_functionpointers.pdfComparison of Text versus Binary Files The following

Example: Record.h

/* C-examples/files/disk_binary_search/Record.h */#ifndef __RECORD_H#define __RECORD_H

#include <stdlib.h>#include <stdio.h>#include "common.h"

typedef struct record Record;typedef struct record * RecordPtr;struct record {

long int key;double value1;double value2;double value3;

};char *toString(RecordPtr record);#endif /* __RECORD_H */

Page 11: #include  FILE *fopen(const char *path, const …cs.boisestate.edu/~alark/cs253/notes/files_functionpointers.pdfComparison of Text versus Binary Files The following

Example: Record.c

/* C-examples/files/disk_binary_search/Record.c */#include "Record.h"

#define MAXLEN 64

char *toString(RecordPtr record){

char *buffer;

buffer = (char *) malloc(sizeof(char)*MAXLEN);sprintf(buffer, "key=%ld values=[%lf, %lf, %lf]\n",record->key, record->value1, record->value2, record->value3);

return buffer;}

Page 12: #include  FILE *fopen(const char *path, const …cs.boisestate.edu/~alark/cs253/notes/files_functionpointers.pdfComparison of Text versus Binary Files The following

Example: ExternalBinarySearch.h

/* C-examples/files/disk_binary_search/ExternalBinarySearch.h */#ifndef __EXTERNALBINARYSEARCH_H#define __EXTERNALBINARYSEARCH_H#include <stdlib.h>#include <stdio.h>#include "common.h"#include "Record.h"

RecordPtr extBinarySearch(FILE *dataFile, unsigned long int key);

#endif /* __EXTERNALBINARYSEARCH_H */

Page 13: #include  FILE *fopen(const char *path, const …cs.boisestate.edu/~alark/cs253/notes/files_functionpointers.pdfComparison of Text versus Binary Files The following

Example: ExternalBinarySearch.c/* C-examples/files/disk_binary_search/ExternalBinarySearch.c */#include "ExternalBinarySearch.h"

RecordPtr extBinarySearch(FILE *dataFile, unsigned long int key){

/* the search window is low..high if we view the dataFile as anarray of record strutures */

long int low = 0;long int mid = 0;long int high = 0;long int pos = 0; /* offset into the file, in bytes */RecordPtr record;

if (dataFile == NULL) return NULL;

/* figure out the size of the file in bytes */fseek(dataFile, 0, SEEK_END);high = ftell(dataFile);

/* set high to number of records in the file */high = high/sizeof(Record);

if (DEBUG >= 2) {fprintf(stderr, "data file has %ld records\n", high);

}

record = (RecordPtr) malloc(sizeof(Record));while (low <= high) {

mid = (low+high)/2;/* calculate byte offset in the file */pos = mid * sizeof(Record);fseek(dataFile, pos, SEEK_SET);fread(record, sizeof(Record), 1, dataFile);if (DEBUG >= 2) {

fprintf(stderr, "low = %ld mid = %ld high = %ld\n",low, mid, high);

fprintf(stderr, "====>record: %s", toString(record));}if (record->key == key) {

return record;} else if (record->key < key) {

low = mid + 1;} else { /* record->key > key */

high = mid - 1;}

}return NULL;

}

Page 14: #include  FILE *fopen(const char *path, const …cs.boisestate.edu/~alark/cs253/notes/files_functionpointers.pdfComparison of Text versus Binary Files The following

Example: TestBsearch.c/* C-examples/files/disk_binary_search/TestBsearch.c */#include <stdlib.h>#include <stdio.h>#include "common.h"#include "Record.h"#include "ExternalBinarySearch.h"

char *program;double getMilliseconds();

void conduct_random_searches(FILE *dataFile, long int n){

long int i;unsigned long int key;Record *record;

for (i=0; i<n; i++) {key = (unsigned long int) random() % MAX_KEY;if (DEBUG >= 1) {

printf("\nSearching for key = %ld\n\n", key);}record = extBinarySearch(dataFile, key);if (DEBUG >= 1) {

if (record) {printf("%s\n", toString(record));printf("found: record with key %ld\n", key);

} else {printf("not found: record with key %ld\n", key);

}}

}}

int main (int argc, char **argv){

int n;long int count;FILE *dataFile;double startTime, totalTime;

program = argv[0];

if (argc != 3) {fprintf(stderr, "Usage: %s <data file name> <number of searches>\n",

program);exit(1);

}n = atoi(argv[2]);dataFile = fopen(argv[1], "r");if (!dataFile) {

perror(program);exit(1);

}fseek(dataFile, 0, SEEK_END);count = ftell(dataFile);count = count/sizeof(Record);if (DEBUG >= 1) {

fprintf(stderr, "data file has %ld records\n", count);}

startTime = getMilliseconds();conduct_random_searches(dataFile, n);totalTime = getMilliseconds() - startTime;printf("Elapsed time for %d searches = %8.2f seconds\n",

n, totalTime/1000.0);

fclose(dataFile);exit(0);

}

Page 15: #include  FILE *fopen(const char *path, const …cs.boisestate.edu/~alark/cs253/notes/files_functionpointers.pdfComparison of Text versus Binary Files The following

Checkpointing to Disk

I The idea is to freeze-dry the state of a program to a binary file ondisk periodically. So if the power goes or the process gets killed it canrestart from the saved state instead of having to start all over again.

I We will look at a checkpoint capable version of the genericdoubly-linked list.

I When do we checkpoint? Several ways:I Checkpoint once every n operations.I Check the time periodically from the code and checkpoint every n

minutes (or hours).I Set up a repeating alarm such that each time the alarm is received

from the operating system, the code checkpoints.

Page 16: #include  FILE *fopen(const char *path, const …cs.boisestate.edu/~alark/cs253/notes/files_functionpointers.pdfComparison of Text versus Binary Files The following

Extra Checkpoint Code for Doubly-Linked Lists/* excerpt from C-examples/files/checkpoint/Job.c */int getJobSize(JobPtr job){

int size = 0;size = sizeof(int) + sizeof(int) + job->infoSize;return size;

}

void checkpointJob(JobPtr job, FILE *fout){

fwrite(&(job->jobid), sizeof(int), 1, fout);fwrite(&(job->infoSize), sizeof(int), 1, fout);fwrite(job->info, job->infoSize, 1, fout);

}

JobPtr restoreJob(FILE *fin){

int jobid;int infoSize;JobPtr job;

fread(&jobid, sizeof(int), 1, fin);fread(&infoSize, sizeof(int), 1, fin);job = createJob(jobid, "");job->info = (char *) malloc(sizeof(char)*infoSize);fread(job->info, infoSize, 1, fin);return job;

}

Page 17: #include  FILE *fopen(const char *path, const …cs.boisestate.edu/~alark/cs253/notes/files_functionpointers.pdfComparison of Text versus Binary Files The following

Extra Checkpoint Code for Doubly-Linked Lists

/* excerpt from C-examples/files/checkpoint/Node.c */int getDataSize(NodePtr node){

return getJobSize(node->data);}

void checkpointNode(NodePtr node, FILE *fout){

checkpointJob(node->data, fout);}

NodePtr restoreNode(FILE *fin){

NodePtr node;JobPtr data;

data = restoreJob(fin);node = createNode(data);return node;

}

Page 18: #include  FILE *fopen(const char *path, const …cs.boisestate.edu/~alark/cs253/notes/files_functionpointers.pdfComparison of Text versus Binary Files The following

Extra Checkpoint Code for Doubly-Linked Lists/* excerpt from C-examples/files/checkpoint/List.c */#define MAX_MSG_LENGTH 1024

Boolean checkpointList(ListPtr list, char *saveFile){

NodePtr node;FILE *fout;char errmsg[MAX_MSG_LENGTH];

if (list == NULL) return TRUE;if (isEmpty(list)) return TRUE;if (saveFile == NULL) return FALSE;if (strlen(saveFile) == 0) return FALSE;fout = fopen(saveFile, "w");if (!fout) {

sprintf(errmsg, "checkpointList: %s",saveFile);perror(errmsg);return FALSE;

}

fwrite(&(list->size), sizeof(int), 1, fout);

node = list->tail;while (node) {

checkpointNode(node, fout);node = node->prev;

}fclose(fout);return TRUE;

}

ListPtr restoreList(char *saveFile){

int size;FILE *fin;ListPtr list;NodePtr node;char errmsg[MAX_MSG_LENGTH];

if (saveFile == NULL) return NULL;if (strlen(saveFile) == 0) return NULL;fin = fopen(saveFile, "r");if (!fin) {

sprintf(errmsg, "restoreList: %s",saveFile);perror(errmsg);return NULL;

}

fread(&size, sizeof(int), 1, fin);if (size <= 0) return NULL;printf("restore: list size = %d\n", size);list = createList();

while (size > 0) {node = restoreNode(fin);addAtFront(list, node);size--;

}

fclose(fin);return list;

}

Page 19: #include  FILE *fopen(const char *path, const …cs.boisestate.edu/~alark/cs253/notes/files_functionpointers.pdfComparison of Text versus Binary Files The following

Extra Checkpoint Code in the Test Suite/* excerpt from C-examples/files/checkpoint/TestSuite.c */const int CHECKPOINT_COUNT = 10000;void runRandomTests(int count, unsigned int seed, int n, ListPtr list){

int i;int test;NodePtr node;JobPtr job;/* rand() and srand() are ANSI C random number generators */srand(seed);for (i=0; i<count; i++) {

if ((i > 0) && ((i % CHECKPOINT_COUNT) == 0)) {fprintf(stderr, "checkpointing list, count = %d\n", i);checkpointList(list, saveFile);

}test = (double)rand() * NUM_TESTS / RAND_MAX;switch (test) {

case 0: ...break;

case 1: ...break;

case 2: ...break;

case 3: ...break;

case 4: ...break;

case 5: ...break;

default:break;

}}

}

Page 20: #include  FILE *fopen(const char *path, const …cs.boisestate.edu/~alark/cs253/notes/files_functionpointers.pdfComparison of Text versus Binary Files The following

Function PointersI The name of a function is a pointer!

int f1(int x); /* prototype */int (*func)(int);

func = f1;n = (*func)(5); /* same as f1(5)

I We can also have an array of function pointers.

int (*bagOfTricks[10])(int, char *);I The prototype for quicksort function in the standard C library uses a function

pointer to enable a generic sort function.void qsort(void *base, size_t nmemb, size_t size,

int(*compar)(const void *, const void *));

Page 21: #include  FILE *fopen(const char *path, const …cs.boisestate.edu/~alark/cs253/notes/files_functionpointers.pdfComparison of Text versus Binary Files The following

test-qsort.c: Function Pointer Example 1

/* C-examples/function-pointers/test-qsort.c */#include <stdlib.h>#include <stdio.h>

/* qsort needs a compare function that returns0 if x ’==’ y<0 if x ’<’ y>0 if x ’>’ y

*/int compareInt(const void *x, const void *y){

return ((*(int *)x) - (*(int *)y));}

struct student {int id;char *name;char *address;

};

int compareId(const void *x, const void *y){

int key1, key2;key1 = ((struct student *)x)->id;key2 = ((struct student *)y)->id;return (key1 - key2);

}

Page 22: #include  FILE *fopen(const char *path, const …cs.boisestate.edu/~alark/cs253/notes/files_functionpointers.pdfComparison of Text versus Binary Files The following

test-qsort.c: Function Pointer Example 1 (contd.)

int main(int argc, char **argv){

int i, n;int *array;char *strings;if (argc != 2) {

fprintf(stderr, "Usage: %s <n>\n", argv[0]) ;exit(1);

}n = atoi(argv[1]);array = (int *) malloc(sizeof(int)*n);srandom(0);for (i=0; i<n; i++) {

array[i] = random() % n;}qsort(array, n, sizeof(int), compareInt);

roster = (struct student *) malloc(sizeof(struct student)*n);for (i=0; i<n; i++) {

roster[i].id = n-i;roster[i].name = NULL;roster[i].address = NULL;

}qsort(roster, n, sizeof(struct student), compareId);

exit(0);}

Page 23: #include  FILE *fopen(const char *path, const …cs.boisestate.edu/~alark/cs253/notes/files_functionpointers.pdfComparison of Text versus Binary Files The following

fun-with-fns.c: Function Pointer Example 2

/* C-examples/function-pointers/fun-with-fns.c */#include <stdio.h>#include <stdlib.h>

int foobar0(int x) {printf("I have been invoked!!!! x=%d\n",x);return x;

}

int foobar1(int x) {printf("I have been invoked!!!! x=%d\n",x*2);return x;

}

int foobar2(int x) {printf("I have been invoked!!!! x=%d\n",x*3);return x;

}void fun(int (*fn)(int x)) {

int result;

result = (*fn) (5);}

Page 24: #include  FILE *fopen(const char *path, const …cs.boisestate.edu/~alark/cs253/notes/files_functionpointers.pdfComparison of Text versus Binary Files The following

fun-with-fns.c: Example 2 (contd.)

int main(int argc, char **argv){

int i;int count=0;int (*names[3])(int);

names[0] = foobar0;names[1] = foobar1;names[2] = foobar2;

if (argc != 2) {fprintf(stderr,"Usage %s: <count>\n",argv[0]);exit(1);

}count = atoi(argv[1]);for (i=0; i<count; i++) {

fun(names[random()%3]);}exit(0);

}

Page 25: #include  FILE *fopen(const char *path, const …cs.boisestate.edu/~alark/cs253/notes/files_functionpointers.pdfComparison of Text versus Binary Files The following

Function Pointer Example 3

typedef struct list List;typedef struct list * ListPtr;

struct list {int size;ListPtr head;ListPtr tail;

ListPtr (*createList)();void (*addAtFront)(ListPtr list, NodePtr node);NodePtr (*removeFront)(ListPtr list);

};

ListPtr myList = (ListPtr) malloc(sizeof(List));/* use my custom functions */myList->createList = myCreate;myList->addAtFront = myAddAtFront;myList->removeFront = myRemoveFront;

/* example of using functions */myList->(*createList)();/* assume node has been created appropriately */myList->(*addAtFront)(list, node);

/* oh...I want a different addAtFront function */myList->addAtFront = anotherAddAtFront;/* below we use the new addAtFront function */myList->(*addAtFront)(list, node);

Page 26: #include  FILE *fopen(const char *path, const …cs.boisestate.edu/~alark/cs253/notes/files_functionpointers.pdfComparison of Text versus Binary Files The following

objects/Address.h: Function Pointer Example 4

/* C-examples/objects/Address.h */#ifndef ADDRESS_H#define ADDRESS_H

#include <stdlib.h>#include <string.h>#include <stdio.h>

typedef struct address address;typedef struct address * Address;

struct address {char *name;char *streetAddress;char *city;char *state;int zip;

char * (*toString)(Address);};

Address createAddress(char *, char *, char *, char *, int);char *toString(Address);char *printAddress(Address);

#endif /* ADDRESS_H */

Page 27: #include  FILE *fopen(const char *path, const …cs.boisestate.edu/~alark/cs253/notes/files_functionpointers.pdfComparison of Text versus Binary Files The following

objects/Address.c: Example 4 (contd.)/* C-examples/objects/Address.c */#include "Address.h"

static int getLength(Address this){

return strlen(this->name)+strlen(this->streetAddress)+strlen(this->city)+strlen(this->state)+4+5+10;

}

Address createAddress(char *name, char *streetAddress, char *city,char *state, int zip)

{Address temp = (Address) malloc(sizeof(address));temp->name = (char *) malloc(sizeof(char)*(strlen(name)+1));temp->streetAddress = (char *)malloc(sizeof(char)*(strlen(streetAddress)+1));temp->city = (char *) malloc(sizeof(char)*(strlen(city)+1));temp->state = (char *) malloc(sizeof(char)*(strlen(state)+1));

strcpy(temp->name, name);strcpy(temp->streetAddress, streetAddress);strcpy(temp->city, city);strcpy(temp->state, state);temp->zip = zip;

temp->toString = toString;return temp;

}

Page 28: #include  FILE *fopen(const char *path, const …cs.boisestate.edu/~alark/cs253/notes/files_functionpointers.pdfComparison of Text versus Binary Files The following

objects/Address.c: (contd.)

char *toString(Address this){

int len = getLength(this);char * temp = (char *) malloc(sizeof(char)*len);snprintf(temp, len, "%s\n%s\n%s, %s, %d\n", this->name,this->streetAddress, this->city, this->state, this->zip);return temp;

}

char *printAddress(Address this){

int len = getLength(this);char * temp = (char *) malloc(sizeof(char)*len);snprintf(temp, len, "%s, %s, %s, %s %d\n", this->name,this->streetAddress, this->city, this->state, this->zip);return temp;

}

Page 29: #include  FILE *fopen(const char *path, const …cs.boisestate.edu/~alark/cs253/notes/files_functionpointers.pdfComparison of Text versus Binary Files The following

objects/testAddress.c: Example 4 (contd.)

/* C-examples/objects/testAddress.c */

#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include "Address.h"

int main(int argc, char *argv[]){

Address addr1 = createAddress("Moo Shoo", "123 Main Street","Boise", "Idaho", 83701);

printf("%s\n", (*addr1->toString)(addr1));

addr1->toString = printAddress;

printf("%s\n", (*addr1->toString)(addr1));

exit(0);}