320 likes | 432 Views
Introduction to ANSI C Part Three. Strings Strings in structs File handling Linked list example. Strings. Recall – strings stored in memory as character codes terminated by 0 So “ABC” stored in 4 locations - maybe: 65, 66, 67, 0
E N D
Introduction to ANSI CPart Three • Strings • Strings in structs • File handling • Linked list example
Strings • Recall – strings stored in memory as character codes terminated by 0 • So “ABC” stored in 4 locations - maybe: • 65, 66, 67, 0 • Character code might be ASCII, or UNICODE or others – not defined in C
Strings as char arrays • For example, char myString[4]; myString[0]='A'; // use ’ for chars myString[1]='B'; myString[2]='C'; myString[3]=0; printf("%s\n",myString); What would happen if we replaced the 4th assignment by: myString[3]=65;
Strings as pointer to char • Recall an array is the same as a pointer to the start of a block of memory • Equivalent to last example: char * myString; myString= (char *) malloc(4); *myString='A'; *(myString+1)='B'; *(myString+2)='C'; *(myString+3)=0; printf("%s\n",myString);
Input and output of strings char * myString; myString= (char *) malloc(10); scanf("%s",myString); printf("%s\n",myString); NB see health warning on next slide
Exercise on string I/O • Run the following program, but type in more than 10 characters: #include <stdio.h> int main() { int x = 5; char myString[10]; scanf("%s",myString); printf("%s\n",myString); printf("%i\n",x); return 0; } Explain what happens
One fix to string input problem char myString[10]; scanf("%10s",myString);
Typical char * processing: count the capital letters int capCount = 0; char * myString = "Born in the USA"; char * where; where = myString; while (*where!=0) { if (*where>='A' && *where<='Z') capCount++; where++; } printf("%i\n",capCount); return 0;
String exercise • Write code like the last example to count the spaces in a string
String constants • For example char * myString = “What a fine day!”; At compile time the assembler – Puts aside enough memory to hold the string Puts appropriate data there (“What a fine.. Generates code to make myString point to that memory
string functions • These are in <string.h> • strcpy(a,b) - copy string b to a, including 0 - return a • strcat(a,b) - concatenate string b to a • strcmp(a,b) - compare - <0 if a<b, 0 if a==b, >0 if a > b • strchr(s,c) - return pointer to first occurence of char c in string s • strlen(s) - return length of string s • plus others
Using string functions char * s1 = "hello"; char * s2; int i; char * where; s2=calloc(80, sizeof(char)); // get some space strcpy(s2, s1); // copy hello into it i = strcmp(s2, s1); // i becomes 0 strcat(s2,s1); // s2 becomes hellohello i = strlen(s2); // i is 10 where = strchr(s2, 'l'); // *where is llohello
String exercise 1. Write a program to test strlen, strcpy, strcat and strcmp 2. Write your own version of strlen
String constants again • In many implementations, string constants are in ‘non-modifiable memory’ • to prevent you doing something like char * s = “Hello”; strcat(s, “Goodbye”); • Correct version - char * s; s = calloc(256, sizeof(char)); strcpy(s,"Hello"); strcat(s,"Goodbye"); printf("%s\n",s);
Tricky string processing // count Capitals in a string again.. int capCount = 0; char * myString; char * where; myString=malloc(50); strcpy(myString,"Born in the USA"); where=myString; while (*where++) if (*(where-1)>='A' && *(where-1)<='Z') capCount++; printf("%i\n",capCount);
Structs again – typical code struct employee { int payrollnumber; int deptCode; }; int main() { struct employee employee1; employee1.payrollnumber=38; printf("%i",employee1.payrollnumber); return 0; }
Struct with string field struct employee { char * name; int payrollnumber; }; void showdetails(struct employee someone) { printf("Name = %s\n",someone.name); printf("Payroll number = %i\n",someone.payrollnumber); return; } int main() { struct employee john; john.name = "John Brown"; john.payrollnumber = 123; showdetails(john); return 0; }
Structs with strings and dynamic memory struct employee { char * name; int deptCode; }; int main() { struct employee * employeePtr; employeePtr = calloc(1, sizeof(struct employee)); employeePtr->deptCode=38; employeePtr->name=malloc(50); strcpy(employeePtr->name,"John Brown"); printf("%s",employeePtr->name); return 0; }
Struct exercise • Modify previous code to have an array of 100 employees. Give data to each one.
Files • ‘Normal’ file is stored on disc (was on tape) or other non-volatile medium • C also uses files called stdin and stdout, which default to keyboard and screen • So input and output is also file-handling • Functions protoyped in stdio.h
File handling • Access is through a pointer to a file declared likeFILE * fp; • File handling is done in a sandwich: open the file read or write it close it
Writing to file 1 External filename FILE * myFile; myFile = fopen("test1.dat", "wb"); fwrite("Hello",5,1,myFile); fclose(myFile); Mode – write binary – deletes existing file Pointer to data, items to write, size each item, filepointer
Writing integer data to file FILE * myFile; int * data = calloc(10, sizeof(int)); int i; for (i=0; i<10; i++) *(data+i)=i; myFile = fopen("test1.dat", "wb"); fwrite(data,10,sizeof(int),myFile); fclose(myFile);
Reading integer data FILE * myFile; int * data = calloc(10, sizeof(int)); int i; myFile = fopen("test1.dat", "rb"); fread(data,10,sizeof(int),myFile); for (i=0; i<10; i++) printf("%i ",*(data+i)); fclose(myFile);
File read write exercise • Define a struct (use the employee one) • Give a struct variable some data • Write it into a disc file • Read the disc file back and display it
Reading text files FILE * myFile; char * myBuffer=malloc(80); myFile = fopen("test2.dat", "r"); while (1) { fgets(myBuffer, 80, myFile); if (feof(myFile)) break; printf("%s",myBuffer); } fclose(myFile);
Text file exercise • Adapt the last example to write a program which counts the lines in a text file.
"r" -- to open an existing text file for reading "w" -- to create a text file or to open and truncate an existing text file, for writing "a" -- to create a text file or to open an existing text file, for writing. The file-position indicator is positioned at the end of the file before each write "rb" -- to open an existing binary file for reading "wb" -- to create a binary file or to open and truncate an existing binary file, for writing "ab" -- to create a binary file or to open an existing binary file, for writing. The file-position indicator is positioned at the end of the file (possibly after arbitrary null byte padding) before each write "r+" -- to open an existing text file for reading and writing "w+" -- to create a text file or to open and truncate an existing text file, for reading and writing "a+" -- to create a text file or to open an existing text file, for reading and writing. The file-position indicator is positioned at the end of the file before each write "r+b" or "rb+" -- to open an existing binary file for reading and writing "w+b" or "wb+" -- to create a binary file or to open and truncate an existing binary file, for reading and writing "a+b" or "ab+" -- to create a binary file or to open an existing binary file, for reading and writing. The file-position indicator is positioned at the end of the file (possibly after arbitrary null byte padding) before each write File open modes -
Using strings again • Task - take a string like “Have a fine day” and split it into separate words, one word in each string • Where to put the word strings - what data structure? • Have an array of pointers to the strings • How many elements? • First count the words • Then get space for the array • Then copy each word somewhere, and point each array element to it
char * s1 = "Have a fine day"; int i, wordcount=1; char *where, *start, *end; char * * pointerstowords; // note the char * * //count the number of words for (where=s1; *where; where++) if ( (*where) == ' ') wordcount++; // make space for the array of pointers pointerstowords = calloc(wordcount, sizeof(char *)); // put all but last word into strings pointed to by array start=s1; for (i=0;i<wordcount-1; i++) { // find first space after start end=strchr(start,' '); // make pointer element point to enough memory pointerstowords[i]=calloc(end-start+2, sizeof(char)); // copy correct number of characters strncpy(*(pointerstowords+i), start, end-start+1); // put 0 at end *(pointerstowords[i]+(end-start)+1)='\0'; // next time, start at letter after the SPACE start=end+1; } // for last word.. point to enough memory.. pointerstowords[wordcount-1]=calloc(strlen(start)+1, sizeof(char)); // copy the word strcpy(*(pointerstowords+wordcount-1), start); *(*(pointerstowords+wordcount-1)+strlen(start)+1)='\0'; // put 0 at end String example
Linked lists • A linked list is a data structure made of a set of nodes, each containing a pointer to the next node 34 21 39 Head pointer As the program runs, calloc and dispose are used to add and remove nodes In general, the nodes will not be next to each other in memory
Linked list implemented struct node { int key; struct node * next; }; int main() { struct node * head; struct node * newnode; head = calloc(1, sizeof(struct node)); head->key = 123; head->next = NULL; newnode = calloc(1, sizeof(struct node)); head->next = newnode; newnode->key = 321; newnode->next = NULL; return 0; } 123 321 head newnode