Anda di halaman 1dari 12

COMPUTER PROGRAMMING

Module 5 Data File Many applications require that information be written to or read from an auxiliary memory device. Such information is stored on the memory device in the form of a data file. Thus, data files allow us to store information permanently, and to access and alter that information, whenever necessary. In C, an extensive set of library functions is available for creating and processing data files. There are two different types of data files, called stream-oriented (or standard) data files, and system oriented !or low level" data files. Stream oriented data files are generally easier to wor# with and are therefore more commonly used. Stream oriented data files can be subdivided into two categories. In the first category are te t !iles, consisting of consecutive characters. These characters can be interpreted as individual data items, or as components of strings or numbers. The second category of stream oriented data files, often referred to as un!ormatted data !iles, organi$es data into bloc#s containing contiguous bytes of information. These bloc#s represent more complex data structures, such as arrays and structures. % separate set of library functions is available for processing stream oriented data files of this type. "#stem-oriented data !iles are more closely related to the computer&s operating system than Stream oriented data files. They are somewhat more complicated to wor# with, though their use may be more efficient for certain #inds of applications. % separate set of procedures, with accompanying library functions, is required to process system oriented data files. Data File

"tandard Data File

"#stem Oriented Data File

Te t

Un!ormatted

O$enin% And Closin% A Data File 'hen wor#ing with a stream oriented data file, the first step is to establish a buffer area, where information is temporarily stored while being transferred between the computer&s memory and the data file. This buffer area allows information to be read from or written to the data file more rapidly than would otherwise be possible. The buffer area is established by writing (I)* +ptvar, where (I)* !uppercase letters required" is a special structure type that establishes the buffer area, and ptvar is a pointer variable that indicates the beginning of the buffer area. The structure type (I)* is defined within a system include file, typically stdio. h. The pointer ptvar is often referred to as a stream pointer, or simply a stream. % data file must be opened before it can be created or processed. This associates the file name with the buffer area !i.e., with the stream". It also specifies how the data file will be utili$ed, i.e., as a read only file, a write only file, or a read-write file, in which both operations are permitted. The library function fopen is used to open a file. This function is typically written as

ptvar . fopen !file name, file type" , 'here file name and file type are strings that represent the name of the data file and the manner in which the data file will be utili$ed. The name chosen for the file name must be consistent with the rules for naming files, as determined by the computer&s operating system. The file type must be one of the strings shown below. File-T#$e & r& &'& &a& (r)& (')& &a)& Meanin% /pen an existing file for reading only. /pen a new file for writing only. If a file with the specified file name currently exists, it will be destroyed and a new file created in its place. /pen an existing file for appending !i.e., for adding new information at the end of the file". % new file will be created if the file with the specified file name does not exist. /pen an existing file for both reading and writing. /pen a new file for both reading and writing. If a file with the specified file name currently exists, it will be destroyed and a new file created in its place. /pen an existing file for both reading and appending. % new file will be created if the file with the specified file name does not exist.

The fopen function returns a pointer to the beginning of the buffer area associated with the file. % 01)) value is returned if the file cannot be opened , for example, when an existing data file cannot be found. (inally, a data file must be closed at the end of the program. This can be accomplished with the library function fclose. The syntax is simply fclose!ptvar", It is good programming practice to close a data file explicitly using the fclose function, though most C compilers will automatically close a data file at the end of program execution if a call to fclose is not present. % C program contains the following statements. 2include 3stdio.h4 (I)* +fpt, fpt . fopen!5sample.dat&, 5w.", ..... fclose!fpt", The first statement causes the header file stdio. h to be included in the program. The second statement defines a pointer called fpt which will point to a structure of type (I)*, indicating the beginning of the data file buffer area. 0ote that (I)* is defined in stdio. h. The third statement opens a new data file called sample. dat as a write only file. Moreover, the fopen function returns a pointer to the beginning of the buffer area and assigns it to the pointer variable fpt. Thus, fpt points to the buffer area associated with the data file sample. dat. %ll subsequent file processing statements !which are not shown explicitly in this example" will access the data file via the pointer variable fpt rather than by the file name. (inally, the last statement closes the data file. 0ote that the argument is the pointer variable fpt, not the file name sample.dat. The value returned by the fopen function can be used to generate an error message if a data file cannot be opened, as illustrated in the next example.

% C program contains the following statements. 2include 3stdio.h4 2define 01)) 6 main!" 7 (I)* +fpt, fpt . fopen!5Sample.dat5, 5r85"9 if !fpt .. 01))" printf!5:n*;;/; Cannot open the designated file:n5", else 7 ..... < fclose !fpt", < This program attempts to open an existing data file called sample. dat for both reading and writing. %n error message will be generated if this data file cannot be found. /therwise the data file will be opened and processed, as indicated. Creatin% A Data File % data file must be created before it can be processed. % stream oriented data file can be created in two ways. /ne is to create the file directly, using a text editor or a word processor. The other is to write a program that enters information into the computer and then writes it out to the data file. 1nformatted data files can only be created with such specially written programs. 'hen creating a new data file with a specially written program, the usual approach is to enter the information from the #eyboard and then write it out to the data file. If the data file consists of individual characters, the library functions getchar and putc can be used to enter the data from the #eyboard and to write it out to the data file. =ere is a program to generate a (ibonacci series and write it into a >ata file. 2 include 3stdio.h4 main!" 7 (I)* +fpt, int a.6,b.?,c,n.?6, fpt.fopen!@fib.datA,AwA", fprintf!fpt,ABd:tBdA,a,b", for!i.6,i3n,i88" 7 c.a8b, fprintf!fpt,ABdA,c", a.b, b.c, < fclose!fpt", < The program begins by defining the stream pointer fpt, indicating the beginning of the data file buffer area. % new data file, called fib.dat, is then opened for writing only. 0ext, a for loop performs a series of operations and writes their result to the data file. The fprintf function is used to write each result to the data file. 0otice that fprintf requires specification of the stream pointer fpt as an argument. Pro*essin% A Data File

Most data file applications require that a data file be altered as it is being processed. (or example, in an application involving the processing of customer records, it may be desirable to add new records to the file !either at the end of the file or interspersed among the existing records", to delete existing records, to modify the contents of existing records, or to rearrange the records. These requirements in turn suggest several different computational strategies. Consider, for example, the problem of updating the records within a data file. There are several approaches to this problem. Cerhaps the most obvious approach is to read each record from a data file, update the record as required, and then write the updated record to the same data file. =owever, there are some problems with this strategy. In particular, it is difficult to read and write formatted data to the same data file without disrupting the arrangement of the data items within the file. Moreover, the original set of records may become inaccessible if something goes wrong during the program execution. %nother approach is to wor# with two different data files an old file !a source" and a new file. *ach , record is read from the old file, updated as necessary, and then written to the new file. 'hen all of the records have been updated, the old file is deleted or placed into archival storage and the new file renamed. =ence, the new file will become the source for the next round of updates. Commonl# Used +uilt-in ,i-rar# Fun*tions =aving opened a file pointer, you will wish to use it for either input or output. C supplies a set of functions to allow you to do this. %ll are very similar to input and output functions that you have already met. Character Input and /utput with (iles D This is done using equivalents of getchar and putchar which are called getc and putc. *ach ta#es an extra argument, which identifies the file pointer to be used for input or output. putchar!c" is equivalent to putc!c,stdout" getchar!c" is equivalent to getc!stdin" (ormatted Input /utput with (ile Cointers D Similarly there are equivalents to the functions printf and scanf which read or write data to files. These are called fprintf and fscanf. The functions are used in the same way, except that the fprintf and fscanf ta#e the file pointer as an additional first argument. fscanf!file pointer, format specifier, Evariable", fprintf!file pointer, format specifier, variables", (ormatted Input /utput with Strings D These are the third set of the printf and scanf families. They are called sprintf and sscanf. sprintf puts formatted data into a string which must have sufficient space allocated to hold it. This can be done by declaring it as an array of char. The data is formatted according to a control string of the same form as that for p rintf. sscanf ta#es 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 v values. ,o' ,e.el Pro%rammin% Re%ister /aria-les ;egister variables are a special case of automatic variables. %utomatic variables are allocated storage in the memory of the computer, however, for most computers, accessing data in memory is considerably slower than processing in the CC1. These computers often have small amounts of storage within the CC1 itself where data can be stored and accessed quic#ly. These storage cells are called registers. 0ormally, the compiler determines what data is to be stored in the registers of the CC1 at what times. =owever, the C language provides the storage class register so that the programmer can FFsuggest&& to the compiler that particular automatic variables should be allocated to CC1 registers, if possible. Thus, register variables provide a certain control over efficiency of program execution. Gariables which are used repeatedly or whose access times are critical, may be declared to be of storage class register.

main!" 7 register float a.6, auto int bb.?, auto char cc.HwH, -+ ;est of the Crogram +< ;egister variables behave in every other way 9ust li#e automatic variables. They are allocated storage upon entry to a bloc#, and the storage is freed when the bloc# is exited. The scope of register variables is local to the bloc# in which they are declared. ;ules for initiali$ations for register variables are the same as for automatic variables. %bove code fragment for a main() function that uses register as well as auto storage class. The class specifier simply precedes the type specifier in the declaration. =ere, the variable, a, should be allocated to a CC1 register by the compiler, while bb and cc will be allocated storage in memory. 0ote, the use of the auto class specifier is optional. %s stated above, the register class designation is merely a suggestion to the compiler. 0ot all implementations will allocate storage in registers for these variables, depending on the number of registers available for the particular computer, or the use of these registers by the compiler. They may be treated 9ust li#e automatic variables and provided storage in memory. (inally, even the availability of register storage does not guarantee faster execution of the program. (or example, if too many register variables are declared, or there are not enough registers available to store all of them, values in some registers would have to be moved to temporary storage in memory in order to clear those registers for other variables. Thus, much time may be wasted in moving data bac# and forth between registers and memory locations. In addition, the use of registers for variable storage may interfere with other uses of registers by the compiler, such as storage of temporary values in expression evaluation. In the end, use of register variables could actually result in slower execution. ;egister variables should only be used if you have a detailed #nowledge of the architecture and compiler for the computer you are using. It is best to chec# the appropriate manuals if you should need to use register variables. +it 0ise O$erations C, in particular, was created to ma#e it easier to write operating systems. The goal was to have a language that provided good control flow, some abstractions !structures, function calls", and could be efficiently compiled and run quic#ly. 'riting operating systems requires the manipulation of data at addresses, and this requires manipulating individual bits or groups of bits. That&s where two sets of operators are usefulD bitwise operators and bitshift operators. Iitwise operators allow you to read and manipulate bits in variables of certain types. If you intend to do some wor# in systems programming, or other forms of low level coding !operating systems, device drivers, soc#et programming, networ# programming", #nowing how to access and manipulate bits is important. Jeneric Iitwise /perations D Iitwise operators only wor# on a limited number of typesD int and *1ar. It turns out there&s more than one #ind of int. In particular, there&s unsi%ned int, there&s s1ort int, there&s lon% int, and then unsigned versions of those ints. The 5C5 language does not specify the difference between a short int, an int and a long int, except to state thatD si$eof! short int " 3. si$eof! int " 3. si$eof! long " Kou will find that these si$es vary from compiler to compiler. The si$es do not have to be distinct. That means all three si$es could be the same, or two of three could be the same, provided that the above restrictions are held. Iitwise operators fall into two categoriesD binary bitwise operators and unary bitwise operators. Iinary operators ta#e two arguments, while unary operators only ta#e one.

+it 0ise O$erators C has distinction of supporting special operators #nown as bit wise operators for manipulation of data at bit level. These operators are used for testing the bits or shifting from left to right. Iitwise operators may not be applied to float and double. +it'ise O$erators !unary" bitwise complement Iitwise MandH Iitwise Mexclusive orH Iitwise Minclusive orH )eft Shift ;ight Shift

)ogical /perators

Shift /perators

L E N O 33 44

)i#e other operators bitwise operators have rules of precedence and associativity that determine how expressions involved them are evaluated. /ne&s Complement /peratorD L D The one&s complement operator, sometimes called the 5bitwise complement5 or 5bitwise 0/T5 operator, produces the bitwise one&s complement of its operand. The operand must be of integral type. This operator performs usual arithmetic conversions, the result has the type of the operand after conversion. 2 6 ? 6 6 In the following example, the new value assigned to y is the one&s complement of the original unsigned short valueD -- *xample of the one&s complement operator unsigned short y . 6x%%%%, -- value of y is 6x%%%% y . Ly, -- value of y is 6xPPPP Iitwise )eft Shift and ;ight Shift /peratorsD 33, 44 D The bitwise shift operators shift their first operand left !33" or right !44" by the number of positions the second operand specifies. In the following example, the right shift operator moves the data bits two positions to the right, thus changing the value of nNumAD -- *xample of the bitwise right shift operator int n0um%.Q, -- beginning value is Q n0um% 44 R, -- ending value is R Iitwise %0> /peratorD E D The bitwise %0> operator !E" compares each bit of its first operand to the corresponding bit of its second operand. If both bits are ?, the corresponding result bit is set to ?. /therwise, the corresponding result bit is set to 6. # 6 ? 6 ? 3# 6 6 6 ?
nNumA

6 6 ? ?

In the following example, the bitwise %0> operator !E" compares the bits of two integers, -- *xample of the bitwise %0> operator int n0um%.?, n0umI.S, n0umC, -- 6666666?, 666666?? n0umC . n0um% E n0umI, -- n0umC is now ?

and nNumBD

Iitwise *xclusive /; /peratorD N D The bitwise exclusive /; operator !N" compares each bit of its first operand to the corresponding bit of its second operand. If one bit is 6 and the other bit is ?, the corresponding result bit is set to ?. /therwise, the corresponding result bit is set to 6.

6 6 ? ?

4 6 ? 6 ?

5# 6 ? ? 6
nNumA

In the following example, the bitwise exclusive /; operator !N" compares the bits of two integers, -- *xample of the bitwise exclusive /; operator int n0um%.T, n0umI.S, n0umC, -- 6666?66?, 666666?? n0umC . n0um% N n0umI, -- n0umC is now ?6D 6666?6?6

and nNumBD

Iitwise Inclusive /; /peratorD O D The bitwise inclusive /; operator !O" compares each bit of its first operand to the corresponding bit of its second operand. If either bit is ?, the corresponding result bit is set to ?. /therwise, the corresponding result bit is set to 6. 4 6 ? 6 ? 6# 6 ? ? ?
nNumA

6 6 ? ?

In the following example, the bitwise inclusive /; operator !O" compares the bits of two integers, -- *xample of the bitwise inclusive /; operator int n0um%.T, n0umI.S, n0umC, -- 6666?66?, 666666?? n0umC . n0um% O n0umI, -- n0umC is now ??D 6666?6??

and nNumBD

Iitwise Shift /perators D The shift operators perform appropriate shift by operator on the right to the operator on the left. The right operator must be positive. The vacated bits are filled with $ero !i.e. There is NO wrap around". (or exampleD x 33 R shifts the bits in x by R places to the left. SoD if x . 666666?6 !binary" or R !decimal" thenD or 6 !decimal" %lsoD if x . 666666?6 !binary" or R !decimal" or Q !decimal" Therefore a shift left is equivalent to a multiplication by R. Similarly a shift right is equal to division by R NOTED Shifting is much faster than actual multiplication !+" or division !-" by R. So if you want fast multiplications or division by R use shifts. +it Fields Iit (ields allow the pac#ing of data in a structure. This is especially useful when memory or data storage is at a premium. Typical examplesD

Cac#ing several ob9ects into a machine word. e.g. ? bit flags can be compacted compilers. ;eading external file formats

Symbol tables in

non standard file formats could be read in. *.g. T bit integers.

C lets us do this in a structure definition by putting Dbit length after the variable. i.e. struct pac#edUstruct 7 unsigned int f?D?, unsigned int fRD?, unsigned int fSD?, unsigned int fVD?, unsigned int typeDV, unsigned int funnyUintDT, < pac#, =ere the packed_struct contains 6 members: Four 1 bit flags f1..f3, a bit funn!_int. bit t!pe and a "

C automatically pac#s the above bit fields as compactly as possible, provided that the maximum length of the field is less than or equal to the integer word length of the computer. If this is not the case then some compilers may allow memory overlap for the fields whilst other would store the next field in the next word. %ccess members as usual viaD pac#.type . W, NOTED /nly n lower bits will be assigned to an n bit number. So type cannot ta#e values larger than ?P !V bits long". Iit fields are always converted to integer type for computation. Kou are allowed to mix FFnormal&& types with bit fields. The unsigned definition is important ensures that no bits are used as a flag.

(requently device controllers !e.g. dis# drives" and the operating system need to communicate at a low level. >evice controllers contain several registers which may be pac#ed together in one integer !See (igure ".

Fi%7 E am$le Dis8 Controller Re%ister 'e could define this register easily with bit fieldsD struct >ISXU;*JIST*; 7

unsigned readyD?, unsigned errorUoccuredD?, unsigned dis#UspinningD?, unsigned writeUprotectD?, unsigned headUloadedD?, unsigned errorUcodeDQ, unsigned trac#DT, unsigned sectorDP, unsigned commandDP, <, To access values stored at a particular memory address, >ISXU;*JIST*;UM*M/;K we can assign a pointer of the above structure to access the memory viaD struct >ISXU;*JIST*; +dis#Ureg . !struct >ISXU;*JIST*; +" >ISXU;*JIST*;UM*M/;K, Enumeration *numerated types contain a list of constants that can be addressed in integer values. 'e can declare types and variables as follows. enum days 7 mon, tues, ..., sun < wee#, enum days wee#?, wee#R, NOTE9 %s with arrays first enumerated name has index value 6. So mon has value 6, tues ?, and so on. wee#? and wee#R are variables. 'e can define other valuesD enum escapes 7 bell . F:a&, bac#space . F:b&, tab . F:t&, newline . F:n&, vtab . F:v&, return . F:r& <, 'e can also override the 6 start valueD enum months 7 9an . ?, feb, mar, ......, dec <, =ere it is implied that feb . R etc. Command ,ine Parameters Command line arguments are parameters supplied to a program from the operating system. These arguments are parameters passed to main function from the operating system. Most versions of C permit two such arguments, which are called argc and argv, respectively. argc must be an integer type variable and argv is an array of pointers to characters i e the array of strings. *ach string in this array will represent a parameter that is passed to main. The value of argc will indicate the number of parameters passed.

The general form of main function will be in the formD main !int argc, char +argvY Z " % program execution is held by specifying the name of the program within a menu driven environment. Some compilers also allow s program to be executed by specifying the name of the program at the operating system level. The name is then interpreted as an operating system command. =ence, the line in which it appears is generally referred to as a command line. *xample main!int argc, char +argvYZ" 7 int i, for!i . 6, i 3 argc, i88" printf!5arg BdD Bs:n5, i, argvYiZ", return 6, < C Pre$ro*essor Creprocessor& is a translation phase that is applied to your source code before the compiler proper gets its hands on it. Jenerally, the preprocessor performs textual substitutions on your source code. Module Cre processor Compiler Code generator %ssembler )in#er Pur$ose Cre process text for input to the compiler Compile pre processed text into intermediate code Jenerate assem-ler *ode for a target machine Compile assembler code into ob9ect modules )in# ob9ect modules into executable code

The pre processor simply processes text, it #nows virtually nothing about C syntax. It scans the input program text, loo#ing for the directives in which the first character on a line is a &2&. 'hen it meets these directives, it ta#es certain actions, including other files to be processed, defining symbols, etc. It acts entirely on the program text and will happily pre process text which may be complete gibberish for the C compiler. This pre processed text is then passed on to the C compiler itself, which chec#s the C syntax and, if it li#es it, consumes it, translating it into some intermediate code which is output, ready for input to the next phase. The C preprocessor provides four separate facilities that you can use as you see fitD Inclusion of header files. These are files of declarations that can be substituted into your program. Macro expansion. Kou can define macros, which are abbreviations for arbitrary fragments of C code, and then the C preprocessor will replace the macros with their definitions throughout the program. Conditional compilation. 1sing special preprocessing directives, you can include or exclude parts of the program according to various conditions. )ine control. If you use a program to combine or rearrange source files into an intermediate file which is then compiled, you can use line control to inform the compiler of where each source line originally came from.

Ma*ros

Creprocessor& is a translation phase that is applied to your source code before the compiler proper gets its hands on it. Jenerally, the preprocessor performs textual substitutions on your source code. Macro is a type of preprocessor which replaces instances of one piece of text with another. % preprocessor line of the form 2define name text defines a macro with the given name, having as its value the given replacement text. %fter that !for the rest of the current source file", wherever the preprocessor sees that name, it will replace it with the replacement text. The name

follows the same rules as ordinary identifiers !it can contain only letters, digits, and underscores, and may not begin with a digit". Since macros behave quite differently from normal variables !or functions", it is customary to give them names which are all capital letters !or at least which begin with a capital letter". The replacement text can be absolutely anything it&s not restricted to numbers, or simple strings, or anything. The most common use for macros is to propagate various constants around and to ma#e them more self documenting. 'e&ve been saying things li#e char lineY?66Z, ... getline!line, ?66", but this is neither readable nor reliable, it&s not necessarily obvious what all those ?66&s scattered around the program are, and if we ever decide that ?66 is too small for the si$e of the array to hold lines, we&ll have to remember to change the number in two !or more" places. % much better solution is to use a macroD 2define M%[)I0* ?66 char lineYM%[)I0*Z, ... getline!line, M%[)I0*", 0ow, if we ever want to change the si$e, we only have to do it in one place. The macro text M%[)I0* is #nown as symbolic constant. Macros with %rguments D Macros can also have arguments, 9ust as functions can. 2define %;*%!x"!S.?V+x+x" Then whenever the preprocessor finds the phrase %;*% !x" it expands it into the statement S.?V + x + x. Ie careful not to leave a blan# space between the macro template and its arguments while defining the macro. The entire macro expansion should also be enclosed within parentheses. 2 define %;*%!x"!S.?V+x+x" 2 include 3stdio.h4 main!" 7 float x.R.P,result, result.%;*%!x", printf!@BfA,result", <

Anda mungkin juga menyukai