CSC209H Lecture 4 Dan Zingaro January 28, 2015
Strings (King Ch 13) String literals are enclosed in double quotes A string literal of n characters is represented as a n+1-character char array C adds a \0 termination character after the string literal s characters String literals cannot be changed (they are read-only) printf ("Hello\n"); char *s = "Hello\n"; s[0] = q ; //Illegal
String Variables Any one-dimensional char array, with a null character at the end, is a string variable #define STR_LEN 80... char s[str_len + 1]; Initializing a string: char course[8] = "csc209h"; //Same as char course[8] = { c, s, c, 2, 0, 9, h, \0 };
String Length and Size Careful: there s an important difference between a string s length and size Length: number of characters before the null character Size: number of bytes allocated (e.g. one more than maximum length) //Size 10, length 3 char s[10] = "abc";
String Functions All of these are declared in string.h. String length: int strlen(const char *str); Copying a string: //Copy all of src (can be unsafe!) char *strcpy(char *dest, const char *src); //Copy at most n chars of src char *strncpy(char *dest, const char *src, int n);
strcpy and strncpy Both strcpy and strncpy return a pointer to dest This pointer is usually ignored, because it equals dest char s1[3]; char s2[5] = "abcd"; strcpy(s1, s2); //Overflow! strncpy(s1, s2, strlen(s2)); //Overflow! strncpy(s1, s2, sizeof(s1) - 1); //correct s1[sizeof(s1) - 1] = \0 ;
Concatenating Strings //Concatenate all of dest (can be unsafe!) char *strcat(char *dest, const char *src); //Add at most n chars from src to dest and add null char *strncat(char *dest, const char *src, int n); char s1[6] = "abc"; strncat (s1, "def", 6); //Overflow! //Correct strncat(s1, "def", sizeof(s1) - strlen(s1) - 1);
Comparing Strings //Return negative number, 0, or positive number //if s1 is <, =, or > s2, respectively int strcmp(const char *s1, const char *s2); There s also an strncmp, but strcmp isn t unsafe (why?) if (strcmp(s1, s2) <= 0) /*s1 <= s2*/
Searching for Characters //Search from left char *strchr(const char *s, int c); //Search from right char *strrchr(const char *s, int c); Both return a pointer to the character if found, NULL pointer if not found
Example: String Functions Problem: given a name string src of the format last first, return a string dest of the form first last. Steps: 1. Calculate the length of src (can use strlen) 2. Allocate space for dest (malloc) 3. Find the space in src (can use strchr) 4. Copy the first name (can use strcpy) 5. Add a space and a null terminator 6. Copy the last name (can use strncat)
What are Structures? (King 16.1-16.3) Data must be same type? Creation Access Array Yes [] syntax a[index] Structure No struct... s.name The following struct has three members. struct student { char first_name[20]; char last_name[20]; int year; };
Declaring Structure Variables Now, we can use struct student as a type, just like int or float Careful: it s struct student; using student by itself is incorrect (but read about typedef to fix this) To make some students and modify them... struct student student1, student2; strcpy(student1.first_name, "Dan"); strcpy(student1.last_name, "Z"); student1.year = 3;...
Structs and Functions Functions can take structs as parameters, and can return a struct back to the caller void printstudent (struct student s) { printf ("First name: %s\n", s.first_name); printf ("Last name: %s\n", s.last_name); printf ("Year: %d\n", s.year); }
Pointers to Structs... struct student student1; struct student *p; p = &student1; We have three ways to access or modify the members of student1 student1.year = 3; (*p).year = 3; p->year = 3; *p.year = 3; /*Wrong!*/
Pointers to Structs... For a function to be able to modify a struct s members, a pointer to the struct must be passed. void changefirst (struct student *s, char *new_first) { strcpy(s->first_name, new_first); }
Structs and Malloc (King Ch 17) malloc is often used in combination with structs (e.g. to create linked lists of structs) Dynamic memory allocation is required because we often don t know how many structs to allocate in advance struct student *s; //Uninitialized pointer! s = malloc (sizeof (student)); //Now s is fine strcpy(s->first_name, "Dan");