CS1061: C Programming Lecture 19: Random Access Files A. O’Riordan, 2004, 2007 updated. Random access files Problems with sequential access files: cannot be modified without the risk of destroying data. cannot jump straight to a particular location in a file. Solution: Random access files. Characteristics of random access: Data in random access files is unformatted (stored as "raw bytes"). All data of the same type (e.g. int) - uses the same amount of memory. Actually random access files are streams of chars since this works with every type. Data not human readable. fwrite() Unformatted output function: fwrite() - transfer bytes from a location in memory to a file Prototype: int fwrite ( const void * array, size_t size, size_t count, FILE * stream ); Example: write an array of ints fwrite(arr, sizeof(int), num, myPtr); arr – location of variable to transfer bytes from sizeof(int) – size of data type num – for arrays, number of elements to transfer myPtr – output stream fread() Unformatted output function: fread() - transfer bytes from a file to a location in memory Prototype: int fread ((void*) ptr, int size, int nitems, FILE* stream); fread() takes four arguments: The first is a void * - this could be an actual char pointer or a char array. The second argument is the size of data type, e.g. char is 1. The third argument in the number of elements to read. The last argument is the stream. fread() (2) fread() returns the number of characters read. Simple example: reading 1 characters from file (inPtr) and storing in char c. fread(&c, 1, 1, inPtr); ~~~~~~~ For detecting the end of the file use feof() pass it a FILE pointer, and if you've reached the end of the file, feof() returns 1, else it returns 0. fread() (3) #include <stdio.h> int main() { FILE *file; char c[30]; /* make sure it is large enough */ int n; if(!(file = fopen("numbers.txt", "r") == NULL)){ n = fread(c, 1, 10, file); c[n] = '\0'; printf("%s\n", c); printf("Characters read: %d\n\n", n); fclose(file); } Example Program: Count characters in file // count total number of character in a file #include <stdio.h> int main(){ FILE * pFile; char c; int n = 0; while ((pFile = fopen("myfile.txt", "rb") != NULL){ fread(&c,1,1,pFile); n++; } fclose(pFile); printf("Total number of bytes: %d\n", n); } fseek() fseek() sets file pointer to a specific position: fseek(stream, offset, symbolic_constant); stream – pointer to FILE offset – file position pointer (0 is first location) symbolic_constant – specifies from where in file offset is applied SEEK_SET – seek starts at beginning of file SEEK_CUR – seek starts at current location in file SEEK_END – seek starts at end of file fseek() example Example – writes “This is a string” and changes it to “This is 1 string”. #include <stdio.h> int main(){ FILE * pFile; char myString= “This is a string”; char one_literal = ‘1’; while ((pFile = fopen("myfile.txt", "wb")) != NULL){ fwrite(myString, 1, 17, pFile,); fseek(pFile, 9, SEEK_SET); fwrite(&one_literal,1,1,pFile); } fclose(pFile); return 0; } sprintf() and sscanf() Formatted Input Output with Strings: These are the third set of the printf() and scanf() families. They are called sprintf() and sscanf(). int sprintf(char *s, const char *format, ...); int sscanf(char *s, const char *format, ...); sprintf() puts formatted data into a string which must have sufficient space allocated to hold it. The data is formatted according to a control string of the same form as that for printf(). sprintf() takes an extra first argument has to be a char * variable. sprintf() returns the number of characters in the string (not included the null character). sscanf() sscanf() takes data from a string and stores it in other variables as specified by the control string. This is done in the same way that scanf() reads input data into variables. sscanf() is very useful for converting strings into numeric values - an alternative to atoi(). Example: char my_date[]="March 17"; char str[20]; int i; sscanf(my_date,"%s %d",str,&i); printf("%s %d\n",str,i);