Computer programming "Education is a progressive discovery of our own ignorance." Will Durant
T.U. Cluj-Napoca - Computer Programming - lecture 8- M. Joldoş
1
Outline
Structure, union, enumeration and user defined data types
Definitions User defined types Example programs
File handling
Low level I/O
open, creat close read write lseek, stat T.U. Cluj-Napoca - Computer Programming - lecture 8- M. Joldoş
2
Structures
Structures = collections of related variables (aggregates) under one name
Can contain variables of different data types Similar to record data type of PASCAL Commonly used to define records to be stored in files Combined with pointers, can create linked lists, stacks, queues, and trees T.U. Cluj-Napoca - Computer Programming - lecture 8- M. Joldoş
3
Structures Definition in BNF: structure_definition ::= structname_identifier { member_list; } variable_identifiers; member_list::=type member_identifier, , member_identifier; type member_identifier, , member_identifier; variable_identifiers::=identifier, identifier Note that in this definition name_identifier and variable_identifiers cannot both be missing; A structure variable of type name_identifier can be later declared using: structure_variable_declaration::=struct name_identifier variable_identifier;
T.U. Cluj-Napoca - Computer Programming - lecture 8- M. Joldoş
4
Structures. Equivalent examples a.
struct material { long code; char name[30]; char uom[10]; float amount; float ppu; } fabric, paper, engine;
b.
struct material { long code; char name[30]; char uom[10]; float amount; float ppu; }; struct material fabric, paper, engine; or material fabric, paper, engine;
c.
struct { long code; char name[30]; char uom[10]; float amount; float ppu; } fabric, paper, engine;
T.U. Cluj-Napoca - Computer Programming - lecture 8- M. Joldoş
5
Structures
struct information
A struct cannot contain an instance of itself Can contain a member that is a pointer to the same structure type A structure definition does not reserve space in memory
Instead creates a new data type used to define structure variables
Valid Operations
Assigning a structure to a structure of the same type Taking the address (&) of a structure Accessing the members of a structure Using the sizeof operator to determine the size of a structure T.U. Cluj-Napoca - Computer Programming - lecture 8- M. Joldoş
6
Structures
Access to members – by qualification Example: fabric.name paper.amount Access to members using pointers: pointer_to_structure-> Example: struct material *p; p=&fabric; p->amount = 20.5; or (*p).amont = 20.5; Structure variables can be allocated like the other variables (simple variables and arrays) T.U. Cluj-Napoca - Computer Programming - lecture 8- M. Joldoş
7
Structure initialization
Initialization is similar to array initialization struct type_name variable_identifier= { value_of_member_1, value_of_member_2, ..., value_of_member_n };
Example: struct material fabric = {1234L, "Wool fabric", "meter", 25.5, 45.3};
Members of
global and static structures are initialized to zero by default automatic structures have undefined values T.U. Cluj-Napoca - Computer Programming - lecture 8- M. Joldoş
8
Structures
Notes In C++ one can assign structure variables of the same type, e.g. material alpha, beta; alpha=beta; Can define recursive structures (heavily used to generate dynamic lists, trees, etc), e.g. struct nodeType { long code; char name[30]; struct nodeType *next; } Node;
T.U. Cluj-Napoca - Computer Programming - lecture 8- M. Joldoş
9
Using structures with functions
Passing structures to functions
In C one can pass a structure only by its address In C++ pass entire structure, e.g. void f(material p, ...)
In C++ to pass structures call-by-reference
Or, pass individual members, e.g. void f(float p.amount, ...) Both pass call by value
Pass its address: void f(material *p, ...) Pass reference to it: void f(material& p, ...)
In C++ to pass arrays call-by-value
Create a structure with the array as a member Pass the structure T.U. Cluj-Napoca - Computer Programming - lecture 8- M. Joldoş
10
Bit Fields (I)
Bit field
Member of a structure whose size (in bits) has been specified Enable better memory utilization Must be defined as int or unsigned Cannot access individual bits
T.U. Cluj-Napoca - Computer Programming - lecture 8- M. Joldoş
11
Bit Fields (II)
Defining bit fields
Follow unsigned or int member with a colon (:) and an integer constant representing the width of the field Example: struct BitCard { unsigned face : 4; unsigned suit : 2; unsigned color : 1; }; T.U. Cluj-Napoca - Computer Programming - lecture 8- M. Joldoş
12
Bit Fields (III)
Unnamed bit field
Field used as padding in the structure Nothing may be stored in the bits struct Example { unsigned a : 13; unsigned : 3; unsigned b : 4; }
Unnamed bit field with zero width aligns next bit field to a new storage unit boundary Demos T.U. Cluj-Napoca - Computer Programming - lecture 8- M. Joldoş
13
Unions
union
Memory that contains a variety of objects over time Only contains one data member at a time Members of a union share space Conserves storage Only the last data member defined can be accessed
union definitions
Same as struct
union Number { int x; float y; }; union Number value; T.U. Cluj-Napoca - Computer Programming - lecture 8- M. Joldoş
14
Unions
Valid union operations
Assignment to union of same type: = Taking address: & Accessing union members: . Accessing members using pointers: ->
Initialization:
In C: not allowed In C++: first member can be initialized T.U. Cluj-Napoca - Computer Programming - lecture 8- M. Joldoş
15
Enumeration
Enumeration
Set of integer constants represented by identifiers Enumeration constants are like symbolic constants whose values are automatically set
Values start at 0 and are incremented by 1 Values can be set explicitly with = Need unique constant names
Example: enum Months { JAN = 1, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC};
Creates a new type enum Months in which the identifiers are set to the integers 1 to 12
Enumeration variables can only assume their enumeration constant values (not the integer representations) T.U. Cluj-Napoca - Computer Programming - lecture 8- M. Joldoş
16
Enumeration BNF definition: enum_definition::= enumname_identifier { enumerator_list} variable identifiers; enumerator_list::= enumerator_identifier , enumerator_identifier variable_identifiers::=identifier, identifier Equivalent examples: a. enum week {Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday}; enum week holiday_week; b. enum week {Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday} holiday_week; c. enum {Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday} holiday_week; Possible assignments: holiday_week=Friday; ... holiday_week=Sunday;
T.U. Cluj-Napoca - Computer Programming - lecture 8- M. Joldoş
17
User-defined data types Type definition uses keyword typedef type_definition::=typedef type type_identifier
Examples: a. typedef struct { int i; float j; double x; } AlphaT; AlphaT y, z; b. typedef struct complex { float re; float im; struct complex *next; } ComplexT; ComplexT x, y;
c. typedef union { char x[10]; long code; } BetaT; BetaT u, v;
d. typedef enum {false, true} BooleanT; BooleanT k, l;
T.U. Cluj-Napoca - Computer Programming - lecture 8- M. Joldoş
18
Example programs. Structures. Operations on complex numbers #include #include typedef struct {float re, im; } ComplexT; /* parameters passed by pointers */ void add(ComplexT *a, ComplexT *b, ComplexT *c) { c->re = a->re + b->re; c->im = a->im + b->im; } void subtract(ComplexT a, ComplexT b, ComplexT *c) /* input parameters passed by value, allowed in C++ only, result passed by pointer */ { c->re = a.re - b.re; c->im = a.im - b.im; }
/* input parameters passed by value, result passed by reference, all allowed in C++ only */ void multiply(ComplexT a, ComplexT b, ComplexT& c) {
c.re = a.re * b.re - a.im * b.im; c.im = a.im * b.re + a.re * b.im;
} /* parameters passed by pointers */ void divide(ComplexT *a, ComplexT *b, ComplexT *c) { float x; x = b->re * b->re + b->im * b->im; if ( x == 0 ) { puts("\nDivision by zero"); exit(1); } else { c->re = (a->re * b->re + a->im * b->im) / x; c->im = (a->im * b->re – a->re * b->im) / x; T.U. Cluj-Napoca - Computer Programming - lecture 8- M. } Joldoş 19 }
Example programs. Structures. Operations on complex numbers void {
readComplex(const char *msg, const char *nbName, ComplexT *nb) printf("\nPlease input the %s complex number\n\t%s.re=", msg, nbName); scanf("%f%*c", &(nb->re)); printf("\t%s.im=", nbName); scanf("%f%*c", &(nb->im));
} int main(int argc, char *argv[]) { ComplexT a, b, c; char ch; ch = 'Y'; while (ch == 'Y' || ch == 'y') { readComplex("first", "a", &a); readComplex("second", "b", &b); T.U. Cluj-Napoca - Computer Programming - lecture 8- M. Joldoş
20
Example programs. Structures. Operations on complex numbers add(&a, &b, &c); printf("\na + b = (%f+j*%f) + (%f+j*%f) = (%f+j*%f)", a.re, a.im, b.re, b.im, c.re, c.im); subtract(a, b, &c); printf("\na - b = (%f+j*%f) - (%f+j*%f) = (%f+j*%f)", a.re, a.im, b.re, b.im, c.re, c.im); multiply(a, b, c); printf("\na * b = (%f+j*%f) * (%f+j*%f) = (%f+j*%f)", a.re, a.im, b.re, b.im, c.re, c.im); divide(&a, &b, &c); printf("\na / b = (%f+j*%f) / (%f+j*%f) = (%f+j*%f)", a.re, a.im, b.re, b.im, c.re, c.im); printf("\nContinue [Y/N]? "); ch = getchar(); } return 0; } T.U. Cluj-Napoca - Computer Programming - lecture 8- M. Joldoş
21
Example programs. Unions #include #include #include union { char ch[10]; short int i; long l; float f; double d; } all; int main(void) { strcpy(all.ch, "ABCDEFGHIJ"); printf("\nThe size of the union is %u bytes\n", sizeof(all)); printf("Area contents:\n\t- as a character string: %s\n", all.ch); printf("\t- as an integer of type short int: %d\n", all.i); printf("\t- as an integer of type long: %ld\n", all.l); printf("\t- as a real of type float: %f\n", all.f); printf("\t- as a real of type double: %g\n", all.d); system("pause"); return 0; } T.U. Cluj-Napoca - Computer Programming - lecture 8- M. Joldoş
22
Example programs. Enumerations #include #include typedef enum {zero, one ,two, three, four, fine} NUM; int main(void) { NUM x, y; int z, w; x = two; /* x=2 */ y = three; /* y = 3 */ z = x + y; w = x * y; printf("\nz=%d w=%d\n", z, w); system("pause"); x = 2; y = 3; /* cause warnings */ z = x + y; w = x * y; printf("\nz=%d w=%d\n", z, w); system("pause"); return 0; } T.U. Cluj-Napoca - Computer Programming - lecture 8- M. Joldoş
23
The Data Hierarchy
Bit - smallest data item Value of 0 or 1 Byte – 8 bits
Used to store a character (decimal digits, letters, and special symbols)
Field - group of characters conveying meaning Example: an address, a name Record – group of related fields Represented a struct (C,C++) or a class (C++) Example: In a payroll system, a record for a particular employee that contained his/her identification number, name, address, etc. File – group of related records Example: payroll file Database – group of related files T.U. Cluj-Napoca - Computer Programming - lecture 9 - M. Joldoş
24
Files
Text files
Characters are (usually) human readable Are divided into lines May contain a special “End-of-file” marker Examples: source files, header files
Binary files
None of the above characteristics Examples: executables, object files, databases, etc. T.U. Cluj-Napoca - Computer Programming - lecture 9 - M. Joldoş
25
Low level I/O
Regardless of the type of file you are reading or writing, the general strategy remains the same: creat() a file or open() a file read() a file write() a file close() a file ALL files are referenced by an integer file
descriptor (0 == STDIN, 1 == STDOUT, 2 == STDERR) T.U. Cluj-Napoca - Computer Programming - lecture 9 - M. Joldoş
26
read() and write()
Low level system calls return a count of the number of bytes processed (read or written)
This count may be less than the amount requested A value of 0 indicates EOF A value of –1 indicates ERROR #include #include int main(int argc, char * argv []) { char buf[BUFSIZ]; int numread; while((numread = read(0, buf, sizeof(buf))) > 0) write(1, buf, numread); exit(0); } Question: Why didn’t we have to open file handles 0 and 1?
T.U. Cluj-Napoca - Computer Programming - lecture 9 - M. Joldoş
27
read() #include ssize_t read(int fd, void * buf, size_t count);
If read() is successful, it returns the number of bytes read If it returns 0, it indicates EOF If unsuccessful, it returns –1 and sets errno Example: read first 20 bytes from "file.dat": int fd, n; char buf[100]; fd = open("File.dat", O_RDONLY); n = read(fd, buf, 20); T.U. Cluj-Napoca - Computer Programming - lecture 9 - M. Joldoş
28
write() #include ssize_t write(int fd, void * buf, size_t count);
If write() is successful, it returns the number of bytes written to the file descriptor, this will usually equal count If it returns 0, it indicates 0 bytes were written If unsuccessful, it returns –1 and sets errno
T.U. Cluj-Napoca - Computer Programming - lecture 9 - M. Joldoş
29
open() #include int open(const char * path, int flags[, mode_t mode]); flags may be OR’d (bitwise) together: O_RDONLY open for reading only O_WRONLY open for writing only O_RDRW open for both reading and writing O_APPEND open for appending to the end of file O_TRUNC truncate to 0 length if file exists O_CREAT create the file if it doesn’t exist path is the pathname of the file to open/create file descriptor is returned on success, -1 on error T.U. Cluj-Napoca - Computer Programming - lecture 9 - M. Joldoş
30
creat()
Dennis Ritchie was once asked what was the single biggest thing he regretted about the C language. He said "leaving off the e on creat()" (i.e create)
The creat() system call creates a file with certain permissions: int creat(const char * filename, mode_t mode);
The mode lets you specify the permissions assigned to the file after creation The file is opened for writing only T.U. Cluj-Napoca - Computer Programming - lecture 9 - M. Joldoş
31
open() (create file)
When we use the O_CREAT flag with open(), we need to define the mode (rights mask from sys/stat.h):
S_IRUSR read permission granted to OWNER
S_IWUSR write permission granted to OWNER
S_IXUSR execute permission granted to OWNER
S_IRGRP read permission granted to GROUP
S_IROTH read permission granted to OTHERS
Opening an existing file with creat destroys its content (truncates file to zero bytes) Example: int fd = open("path_to_file", O_CREAT, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IROTH); T.U. Cluj-Napoca - Computer Programming - lecture 9 - M. Joldoş
32
close()
#include int close( int fd ); close() closes a file descriptor (fd) that has been opened. Closing a file has the following consequences:
The file descriptor is deallocated. Any record locks owned by the process on the file are unlocked. When all file descriptors associated with a pipe or FIFO have been closed, any unread data is discarded. T.U. Cluj-Napoca - Computer Programming - lecture 9 - M. Joldoş
33
File positioning: lseek() #include #include long lseek(int fd, long offset, int startingpoint) lseek moves the current file pointer of the file associated with file descriptor fd to a new position for the next read/write call offset is given in number of bytes, either positive or negative from startingpoint startingpoint may be one of: SEEK_SET move from beginning of the file SEEK_CUR move from current position SEEK_END move from the end of the file Example: int d1, d2; char buf[4]; d1 = open ("foo", O_RDONLY); d2 = open ("foo", O_RDONLY); lseek (d1, 1024, SEEK_SET); T.U. Cluj-Napoca - Computer Programming - lecture 9 - M. read (d2, buf, 4); Joldoş
34
Error Handling
System calls set a global integer called errno on error: extern int errno; /* defined in errno.h */ The constants that errno may be set to are defined in . For example: EPERM operation not permitted ENOENT no such file or directory (not there) EIO I/O error EEXIST file already exists ENODEV no such device exists EINVAL invalid argument passed #include void perror(const char * s); E.G. if errno==EINVAL, then perror("EINVAL: "); prints: EINVAL: : Invalid argument T.U. Cluj-Napoca - Computer Programming - lecture 9 - M. Joldoş
35
File status
int stat(const char * pathname, struct stat *buf); The stat() system call returns a structure (into a buffer you pass in) representing all the stat values for a given filename. This information includes: the file’s mode (permissions) inode number (in Unix) number of hard links user id of owner of file group id of owner of file file size last access, modification, change times see header file stat.h and sys/types.h (S_IFMT, S_IFCHR, etc.) T.U. Cluj-Napoca - Computer Programming - lecture 9 - M. Joldoş
36
File status example #include #include #include #include int main(int argc, char *argv[]) { char *fname="main.c"; struct stat statBuf;
printf("\tinode=%u\n\tdevice=%c :", statBuf.st_ino, statBuf.st_dev+'A');
printf("\n\tlinks=%d\n\tuid=%d\ n\tgid=%d\n\tsize=%ld", statBuf.st_nlink, statBuf.st_uid, statBuf.st_gid, if (0==stat(fname, &statBuf)) statBuf.st_size); { printf("\n\taccess printf("\nFile: %s", fname); time=%s\tcontents mod if (S_ISDIR (statBuf.st_mode)) time=%s\tattrib mod time=%s", puts("\n\tdirectory"); ctime(&statBuf.st_atime), if (S_ISCHR(statBuf.st_mode)) puts("\n\tcharacter special file"); ctime(&statBuf.st_mtime), ctime(&statBuf.st_ctime)); if (S_ISBLK(statBuf.st_mode)) } puts("\n\tblock special file"); else perror(0); if (S_ISREG(statBuf.st_mode)) puts("\n\tregular file"); system("PAUSE"); if (S_ISFIFO(statBuf.st_mode)) return 0; puts("\n\tFIFO special file, or a pipe"); } T.U. Cluj-Napoca - Computer Programming - lecture 9 - M. Joldoş
37
File status example
Program output example:
File: main.c regular file inode=0 device=D: links=1 uid=0 gid=0 size=1007 access time=Thu Dec 21 08:47:51 2005 contents mod time=Thu Dec 21 08:47:51 2005 attrib mod time=Thu Dec 21 08:47:51 2005
T.U. Cluj-Napoca - Computer Programming - lecture 9 - M. Joldoş
38
Low level file I/O program example #include #include #include #include #include #include #include
typedef struct { char name[60]; float average; } StudentT;
typedef union { StudentT stud; char st[sizeof(StudentT)]; } BufferT; typedef struct { int nb; float average; } ElementT; typedef enum {FALSE, TRUE} BooleanT;
T.U. Cluj-Napoca - Computer Programming - lecture 9 - M. Joldoş
39
Low level file I/O program example void sort(const char filename[], const char sorted_filename[]) { ElementT el, t[100]; char msgBuf[201]; int i, j, n, fd1, fd2; BooleanT flag; BufferT stu; /* read file to array t */ j = 0; fd1 = open(filename, O_RDONLY); while ( read(fd1, stu.st, sizeof(BufferT)) > 0 && j < 100) { t[j].nb = j; t[j].average = stu.stud.average; j++; } n = j;
T.U. Cluj-Napoca - Computer Programming - lecture 9 - M. Joldoş
40
Low level file I/O program example
}
/* sort array t by average */ j = 0; do { flag = TRUE; for (i = 1; i < n - j ; i++) if (t[i-1].average < t[i].average) { memcpy(&el, &t[i-1], sizeof(ElementT)); memcpy(&t[i-1], &t[i], sizeof(ElementT)); memcpy(&t[i], &el, sizeof(ElementT)); flag = FALSE; } } while (flag == FALSE); /* write sorted output */ if ((fd2 = open(sorted_filename, O_CREAT | O_WRONLY | O_TRUNC, S_IREAD | S_IWRITE)) < 0) { sprintf(msgBuf, "\nCannot create %s. ", sorted_filename); perror(msgBuf); getchar(); exit(1); } for (i = 0; i < n; i++) { lseek(fd1, (long)(t[i].nb *sizeof(BufferT)), SEEK_SET); read(fd1, stu.st, sizeof(BufferT)); write(fd2, stu.st, sizeof(BufferT)); } close(fd1); close(fd2); T.U. Cluj-Napoca - Computer Programming - lecture 9 - M. Joldoş
41
Low level file I/O program example void show_students(char filename[]) { BufferT stu; char s[41]; int j, fd1; if ((fd1 = open(filename, O_RDONLY)) < 0) { sprintf(s, "Cannot open %s for reading. ", filename); perror(s); getchar(); exit(3); }
}
memset(&stu, '\0', sizeof(BufferT)); j = 0; while ( read(fd1, stu.st, sizeof(BufferT)) > 0) { printf("\n%d. %-60s %7.2f", j++, stu.stud.name, stu.stud.average); memset(&stu, '\0', sizeof(BufferT)); } close(fd1); T.U. Cluj-Napoca - Computer Programming - lecture 9 - M. Joldoş
42
Low level file I/O program example int main(int argc, char *argv[]) { unsigned int i, n; int fd1; long l; char ch; BufferT stu; float avgAux; char nameAux[sizeof(stu.stud.name)]; char filename[] = "Group.dat"; char sorted_filename[] = "SortedGroup.dat"; printf("\nNumber of students in the group= "); scanf("%u%*c", &n); /* create group file */ if ((fd1 = open(filename, O_CREAT | O_WRONLY | O_TRUNC, S_IREAD | S_IWRITE)) < 0) { perror("\nCannot create Group.dat. "); getchar(); exit(1); } T.U. Cluj-Napoca - Computer Programming - lecture 9 - M. Joldoş
43
Low level file I/O program example /* student data input */ for (i = 1; i