09.07.2015 Views

Standard Input/Output Library - University of Windsor

Standard Input/Output Library - University of Windsor

Standard Input/Output Library - University of Windsor

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

Content60-256 System Programming:<strong>Standard</strong> <strong>Input</strong>/<strong>Output</strong> <strong>Library</strong>by Dr. B. BoufamaSchool <strong>of</strong> Computer Science<strong>University</strong> <strong>of</strong> <strong>Windsor</strong>–Instructor: Dr. A. Habedadlane@cs.uwindsor.cahttp://cs.uwindsor.ca/∼adlane/60-256<strong>Standard</strong> <strong>Input</strong>/<strong>Output</strong> <strong>Library</strong>60-256 System Programming


ContentContent1 Introduction2 Streams and FILE objects3 BufferingFully buffered I/OLine buffered I/OUnbuffered I/OANSI C buffering requirementsChanging the default bufferingExamples4 Opening a Stream5 Reading and writing a stream<strong>Standard</strong> <strong>Input</strong>/<strong>Output</strong> <strong>Library</strong>60-256 System Programming


IntroductionStreams and FILE objectsBufferingOpening a StreamReading and writing a streamIntroductionThe <strong>Standard</strong> <strong>Input</strong>/<strong>Output</strong> <strong>Library</strong> was written by DennisRitchie around 1975.This library is specified by the ANSI C standard because it hasbeen implemented on different operating systems.This library handles details such asbuffer allocationperforming I/O in optimal-sized chunksThe header file <strong>of</strong> this library is /usr/include/stdio.h<strong>Standard</strong> <strong>Input</strong>/<strong>Output</strong> <strong>Library</strong>60-256 System Programming


IntroductionStreams and FILE objectsBufferingOpening a StreamReading and writing a streamStreams and FILE objectsOpening or creating a file → associating a stream with the file.fopen()The function fopen() returns a pointer to the a FILE object.A FILE object is a structure that contains all neededinformation to manage a stream:the file descriptor: a nonnegative integer used for theactual I/Oa pointer to a buffer for the streamthe size <strong>of</strong> the buffera count <strong>of</strong> the characters currently in the bufferan error flagan end-<strong>of</strong>-file flagNormally, an application s<strong>of</strong>tware never needs to examine theFILE object.<strong>Standard</strong> <strong>Input</strong>/<strong>Output</strong> <strong>Library</strong>60-256 System Programming


BufferingIntroductionStreams and FILE objectsBufferingOpening a StreamReading and writing a streamFully buffered I/OLine buffered I/OUnbuffered I/OANSI C buffering requirementsChanging the default bufferingExamplesGoal <strong>of</strong> bufferingMinimize the number <strong>of</strong> I/O system calls.There are three types <strong>of</strong> buffering provided:fully buffered,line buffered,unbuffered.<strong>Standard</strong> <strong>Input</strong>/<strong>Output</strong> <strong>Library</strong>60-256 System Programming


Fully buffered I/OIntroductionStreams and FILE objectsBufferingOpening a StreamReading and writing a streamFully buffered I/OLine buffered I/OUnbuffered I/OANSI C buffering requirementsChanging the default bufferingExamplesIn the case <strong>of</strong> fully buffered I/O, actual I/O take place onlywhen the I/O buffer is full.Disk files are fully buffered by the standard I/O library.The buffer is usually created using malloc the first timeI/O is performed on a stream.Flushing buffersWe can call the function fflush() to flush a stream forcing itsassociated buffer to be written even when it is partially filled.Syntax:int fflush(FILE *fp)When fp is NULL, fflush() causes all output streams to beflushed.<strong>Standard</strong> <strong>Input</strong>/<strong>Output</strong> <strong>Library</strong>60-256 System Programming


Unbuffered I/OIntroductionStreams and FILE objectsBufferingOpening a StreamReading and writing a streamFully buffered I/OLine buffered I/OUnbuffered I/OANSI C buffering requirementsChanging the default bufferingExamplesIn this case, the standard I/O library does not buffer thecharacters.→ each time we print or read a single character, the actual I/Ooperation takes place.For example, the standard error stream is normally unbuffered.<strong>Standard</strong> <strong>Input</strong>/<strong>Output</strong> <strong>Library</strong>60-256 System Programming


IntroductionStreams and FILE objectsBufferingOpening a StreamReading and writing a streamANSI C buffering requirementsFully buffered I/OLine buffered I/OUnbuffered I/OANSI C buffering requirementsChanging the default bufferingExamplesANSI C requires the following buffering characteristics:1 <strong>Standard</strong> I/O are fully buffered if and only if they do notrefer to an interactive device.2 <strong>Standard</strong> error is never fully buffered.<strong>Standard</strong> <strong>Input</strong>/<strong>Output</strong> <strong>Library</strong>60-256 System Programming


IntroductionStreams and FILE objectsBufferingOpening a StreamReading and writing a streamChanging the default bufferingFully buffered I/OLine buffered I/OUnbuffered I/OANSI C buffering requirementsChanging the default bufferingExamplesWe can change the default buffering using:void setbuf(FILE *fp, char *buf);If buf is NULL then, buffering is disabled.Otherwise, buf must point to a buffer <strong>of</strong> length BUFSIZ.void setvbuf(FILE *fp, char *buf, int mode,size t size);This function can specify which buffering we wantdepending on the value <strong>of</strong> mode:IOFBF: fully bufferedIOLBF: line bufferedIONBF: unbufferedNote that when an unbuffered stream is specified, the bufand size arguments are ignored.<strong>Standard</strong> <strong>Input</strong>/<strong>Output</strong> <strong>Library</strong>60-256 System Programming


Example 1IntroductionStreams and FILE objectsBufferingOpening a StreamReading and writing a streamFully buffered I/OLine buffered I/OUnbuffered I/OANSI C buffering requirementsChanging the default bufferingExamples#include #include // This is needed for sleep()int main(void){ // without fflushint i=0;char line[100]="Hello, my name No-Name\n";while(line[i] != NULL){putchar(line[i++]);sleep(1);}}<strong>Standard</strong> <strong>Input</strong>/<strong>Output</strong> <strong>Library</strong>60-256 System Programming


Example 2IntroductionStreams and FILE objectsBufferingOpening a StreamReading and writing a streamFully buffered I/OLine buffered I/OUnbuffered I/OANSI C buffering requirementsChanging the default bufferingExamples#include #include // This is needed for sleep()int main(void){// forcing the flush with fflushint i=0;char line[100]="Hello, my name No-Name\n";while(line[i] != NULL){putchar(line[i++]);fflush(stdout); // flush std output buffersleep(1);}}<strong>Standard</strong> <strong>Input</strong>/<strong>Output</strong> <strong>Library</strong>60-256 System Programming


Example 3IntroductionStreams and FILE objectsBufferingOpening a StreamReading and writing a streamFully buffered I/OLine buffered I/OUnbuffered I/OANSI C buffering requirementsChanging the default bufferingExamples#include #include // needed for sleep()int main(int argc, char *argv[]){}while(1){printf("Hello, program is runing right now");sleep(1);}<strong>Standard</strong> <strong>Input</strong>/<strong>Output</strong> <strong>Library</strong>60-256 System Programming


Opening a StreamIntroductionStreams and FILE objectsBufferingOpening a StreamReading and writing a streamThree functions can be used to open a standard I/O stream:FILE *fopen(const char *f, const char *t)this is the most used one.Example: file = fopen(‘‘./data.txt’’, ‘‘r’’)FILE *freopen(const char *f, const char *t,FILE *fp)Opens a specified file on a specified stream, closing thestream first if it was already open.FILE *fdopen(int filedesc, const char *t)This function associates a standard I/O stream with anexisting file descriptor (the filedesc argument).<strong>Standard</strong> <strong>Input</strong>/<strong>Output</strong> <strong>Library</strong>60-256 System Programming


File descriptorsIntroductionStreams and FILE objectsBufferingOpening a StreamReading and writing a streamA file descriptor is a nonnegative integer used by thekernel to specify any open file.A file descriptor is typically returned by the system callopen() that opens/creates a file, a pipe or, a networkcommunication channel.The function fopen() cannot be used to open a pipe or anetwork communication channel→ we use the system call open() to get a file descriptor fora pipe or a channel, then we use fdopen() to associate itwith a standard stream.<strong>Standard</strong> <strong>Input</strong>/<strong>Output</strong> <strong>Library</strong>60-256 System Programming


Argument typesIntroductionStreams and FILE objectsBufferingOpening a StreamReading and writing a streamThe argument type, const char *t, specifies how a streamis to be opened.The possible values <strong>of</strong> type are :r for read, w for write, a for append at the end <strong>of</strong> the file, r+ forread and write, w+ for read and write and, a+ for read and writeat the end <strong>of</strong> the file.SummaryRestrictions r w a r+ w+ a+File must exist already ∗ ∗Previous contents <strong>of</strong> file lost ∗ ∗Stream can be read ∗ ∗ ∗ ∗Stream can be written ∗ ∗ ∗ ∗ ∗Stream can be written only ∗ ∗at end<strong>Standard</strong> <strong>Input</strong>/<strong>Output</strong> <strong>Library</strong>60-256 System Programming


RestrictionsIntroductionStreams and FILE objectsBufferingOpening a StreamReading and writing a streamWhen a file is open for read and write, the following restrictionsapply:<strong>Output</strong> cannot be directly followed by input without anintervening fflush, fseek, fsetpos, or rewind.<strong>Input</strong> cannot be directly followed by output without anintervening fseek, fsetpos, rewind or, an inputoperation that encounters an EOF.int fclose(FILE *fp)int fclose(FILE *fp) closes any opened stream. Inparticular:Any buffered output data is flushed,Any buffered input data is discarded,Any allocated buffer is released.Note that when a process terminates normally, all openstandard I/O streams are closed.<strong>Standard</strong> <strong>Input</strong>/<strong>Output</strong> <strong>Library</strong>60-256 System Programming


Unformatted I/OIntroductionStreams and FILE objectsBufferingOpening a StreamReading and writing a streamThere are 3 types <strong>of</strong> unformatted I/O:Single-character I/OLine I/O: to read or write a line at a timeDirect I/O: also called binary I/O. Useful when dealing withstructures and binary information.<strong>Standard</strong> <strong>Input</strong>/<strong>Output</strong> <strong>Library</strong>60-256 System Programming


IntroductionStreams and FILE objectsBufferingOpening a StreamReading and writing a streamSingle-character <strong>Input</strong> functionsint getc(FILE *), int fgetc(FILE *) andint getchar(void).We have:getchar(void) is equivalent to getc(stdin).getc() can be implemented as a macro whereasfgetc() cannot.→ getc is more efficient,→ the address <strong>of</strong> fgetc can be passed as a parameterunlike getc (macros do not have addresses).Important issues about these functionsThey return the next character as an unsigned charconverted into an int. Reason: the high order bit is set withoutcausing the return value to be negative.→ we can read all possible 255 different values <strong>of</strong> a byte. Inparticular, we will never get a character with -1(EOF) as itsvalue.→ The return value from these functions can’t be stored in achar variable then compared to EOF<strong>Standard</strong> <strong>Input</strong>/<strong>Output</strong> <strong>Library</strong>60-256 System Programming


Example...IntroductionStreams and FILE objectsBufferingOpening a StreamReading and writing a stream#include int main(int argc, char *argv[]){FILE *fd;char ch;int fileSize=-1;}fd = fopen(argv[1], "r");do{ch=getc(fd);fileSize++;} while( ch != EOF);printf("Size <strong>of</strong> %s is %d\n", argv[1], fileSize);./size size.c → Size <strong>of</strong> size.c is 242 (correct size)<strong>Standard</strong> <strong>Input</strong>/<strong>Output</strong> <strong>Library</strong>60-256 System Programming


...ExampleIntroductionStreams and FILE objectsBufferingOpening a StreamReading and writing a streamThis can be solved simply by using int instead <strong>of</strong> char.#include int main(int argc, char *argv[]){FILE *fd;int ch;int fileSize=-1;//ÿfd = fopen(argv[1], "r");do{ch=getc(fd);fileSize++;} while( ch != EOF);printf("Size <strong>of</strong> %s is %d\n", argv[1], fileSize);}./size size.c → Size <strong>of</strong> size.c is 259 (correct size)<strong>Standard</strong> <strong>Input</strong>/<strong>Output</strong> <strong>Library</strong>60-256 System Programming


IntroductionStreams and FILE objectsBufferingOpening a StreamReading and writing a streamNote that these 3 functions return -1 whether an error or theend-<strong>of</strong>-file occurs.How to differentiate between the 2 situations?For each stream, two flags are maintained in the FILE object:an error flag and an end-<strong>of</strong>-file flag.The following three functions should be used to access theseflags:int ferror(FILE*)returns nonzero for true, 0 otherwiseint fe<strong>of</strong>(FILE*)returns nonzero for true, 0 otherwisevoid clearerr(FILE*)clears both the error and the end-<strong>of</strong>-file flags.<strong>Standard</strong> <strong>Input</strong>/<strong>Output</strong> <strong>Library</strong>60-256 System Programming


IntroductionStreams and FILE objectsBufferingOpening a StreamReading and writing a streamPushing back a characterint ungetc(int c, FILE *fp)The function int ungetc(int c, FILE *fp)Return c if OK, -1 otherwise.This function is used to push back a character after readingfrom a stream.This is useful when we need to peek at the next character todetermine what to do next.Note that:The pushed-back character does not have to be the sameas the one that was read.We cannot push back EOFWe can push back a character after end-<strong>of</strong>-file is reached.Then, we can read that character because ungetc() clearsthe end-<strong>of</strong>-file flag <strong>of</strong> the stream.<strong>Standard</strong> <strong>Input</strong>/<strong>Output</strong> <strong>Library</strong>60-256 System Programming


IntroductionStreams and FILE objectsBufferingOpening a StreamReading and writing a streamSingle-character <strong>Output</strong> functionsint putc(int c, FILE *fp): print a single characterint fputc(int c, FILE *fp): same as putc()except that, putc() can be implemented as a macrowhereas fputc() cannot.int putchar(int c): equivalent to putc(c, stdin).All these functions return the printed character c as an intwhen successful and -1 otherwise.<strong>Standard</strong> <strong>Input</strong>/<strong>Output</strong> <strong>Library</strong>60-256 System Programming


ExampleIntroductionStreams and FILE objectsBufferingOpening a StreamReading and writing a stream#include int main(int argc, char *argv[]){FILE *f;char c;}f=fopen(argv[1], "w");while((c=getchar()) != EOF)fputc(c, f);Question: what happens if we exit with a CTRL-C?<strong>Standard</strong> <strong>Input</strong>/<strong>Output</strong> <strong>Library</strong>60-256 System Programming


ExampleIntroductionStreams and FILE objectsBufferingOpening a StreamReading and writing a streamIf this is a serious issue, then we should modify our code to:#include int main(int argc, char *argv[]){FILE *f;char c;f=fopen(argv[1], "w");setbuf(f, NULL);while((c=getchar()) != EOF)fputc(c, f);}or to#include int main(int argc, char *argv[]){FILE *f;char c;f=fopen(argv[1], "w");while((c=getchar()) != EOF){fputc(c, f);fflush(f);}}<strong>Standard</strong> <strong>Input</strong>/<strong>Output</strong> <strong>Library</strong>60-256 System Programming


IntroductionStreams and FILE objectsBufferingOpening a StreamReading and writing a streamString/Line <strong>Input</strong> functions<strong>Input</strong> functions:char *fgets(char *dest, int n, FILE *fp)Reads up through, including, the next newline, but no morethan n-1 characters. Then NULL added to whatever hasbeen read.char *gets(char *dest)Reads from stdin in a similar way as fgets(), but hassome serious side effects. In particular, it allows buffer tooverflow. It should never be used!Note that dest is the address <strong>of</strong> the array to read thecharacters into it. Both functions return dest if OK, NULLotherwise (end-<strong>of</strong>-file or error).<strong>Standard</strong> <strong>Input</strong>/<strong>Output</strong> <strong>Library</strong>60-256 System Programming


IntroductionStreams and FILE objectsBufferingOpening a StreamReading and writing a streamString/Line <strong>Output</strong> functions<strong>Output</strong> functions:fputs(const char *str, FILE *fp)Write the NULL terminated string, stored in str, to astream.puts(const char *str)Write the NULL terminated string, stored in str, to stdoutand add a newline character at the end.Note that NULL character at the end is not written by bothfunctions.<strong>Standard</strong> <strong>Input</strong>/<strong>Output</strong> <strong>Library</strong>60-256 System Programming

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!