C Strings

  1. Background
    1. A string is a sequence of characters
    2. Useful for storing names, phone numbers, lines of text, etc.
    3. Two ways of working with strings in C++
      1. C Strings (the old way) - using char arrays
      2. C++ Strings (the new way) - using the string data type (class)
    4. There are billions of lines of active code written using string the C way, so we will spend some time familiarizing ourselves with this method
    5. Most new development uses C++ strings because they are somewhat easier to work with and don't share some of the problems that char array have
  2. C strings
    1. Declaring
      1. Use a char array
        		// String for storing a name
        		char name[20];
        		
      2. String can be initialized at time of declaration
        // Make name contain Smith
        char name[20] = "Smith";
        
        // WRONG! Can't assign a string after declaration
        name = "White";
        
      3. Leaving out the size of the array makes the array just large enough for holding the literal plus one slot for the null terminator (defined next)
        // name has size of 6
        char name[] = "Smith";
        
    2. Null terminators
      1. Char arrays use a null terminator (ASCII value of 0) to indicate where the string ends
      2. Represented in C++ as \0
      3. So null terminator is in slot N when the string contains N chars
        char name[20] = "Bob";
        
        name = B o b \0 ? ? ?     ?
         slots 0 1 2 3  4 5 6 ... 19
        
      4. The longest string that a char array can hold must include one slot for the null terminator
        // WRONG! There's no slot available for \0
        char name[5] = "Becky";
        
    3. Input and output
      1. Basic I/O
        char name[20];
        
        cout << "Name? ";
        cin >> name;
        cout << "Hello, " << name << "!";
        
        Name? Bob
        Hello, Bob!
        
        1. If user enters more than 19 chars, program will crash since array can only hold 19 chars + null terminator
        2. cout statement knows to stop outputting chars when it hits the null terminator
      2. Input containing a space
        1. cin statement stops adding chars to the char array when it encounters white space (space, tab, carriage return)
          char name[20];
          
          cout << "Name? ";
          cin >> name;
          cout << "Hello, " << name << "!";
          
          Name? Bob Smith
          Hello, Bob!
          
        2. Use getline function to read all chars including space
          char name[20];
          
          cout << "Name? ";
          cin.getline(name, 20);
          cout << "Hello, " << name << "!";
          
          Name? Bob Smith
          Hello, Bob Smith!
          
        3. Second arg to getline is the size of the array
        4. getline is safer for reading input because if the user enters more than 19 chars, only the first 19 chars will be placed in the array
    4. Collection of chars
      1. Because a string is just a char array, you can access each char using [index]
        char cheer[50] = "Let's go Bisons!";
        
        cout << cheer[0];   // L
        cheer[9] = 'M';     // Changes B to M
        cout << cheer;      // Let's go Misons!
        
      2. You can loop through the entire string
        char cheer[50] = "Let's go Bisons!";
        
        // Count how many spaces are in the string
        int spaces = 0;
        for (int i = 0; cheer[i] != '\0'; i++)
           if (cheer[i] == ' ')
              spaces++;
        	  
        cout << "Total spaces: " << spaces;
        
      3. Another example which capitalizes the entire string
        char cheer[50] = "Let's go Bisons!";
        
        // Capitalize every letter
        for (int i = 0; cheer[i] != '\0'; i++)
           cheer[i] = toupper(cheer[i]);
        	  
        cout << cheer;  // LET'S GO BISONS!
        
  3. C string functions
    1. Include cstring library to use functions that operate on char arrays
    2. cstring contains over 20 functions, but we will cover only 4 here
    3. String assignment
      1. strcpy_s(dest, src) - Replace the dest string with the src string
        char s[10] = "Goodbye";
        strcpy_s(s, "Hello");
        cout << s;    // Hello
        
      2. src can be a char array or a literal
      3. Be careful! src must be small enough to fit in the dest string or your program will go outside the array bounds and crash!
    4. String concatenation
      1. Concatenation means to link things together in a chain or series
      2. strcat_s(dest, src) - Append src onto the back of dest
        char s[10] = "Hey";
        strcat_s(s, " there");
        cout << s;    // Hey there
        
      3. src can be a char array or a literal
      4. Be careful! If dest isn't large enough to hold the appended string then your program will go beyond the array bounds
    5. String length
      1. strlen(s) - Return the number of chars in s before the null terminator
        char s[10] = "Hey";
        cout << strlen(s);    // 3
        
      2. s can be a char array or a literal
      3. You can change the length of a string by manipulating the location of the null terminator
        char s[] = "How are you?";
        cout << strlen(s);    // 12
        
        s[3] = '\0';          // Replace space after "How" with null terminator
        cout << s;            // How
        cout << strlen(s);    // 3
        
    6. String comparison
      1. strcmp function compares ASCII values of chars in two arrays
      2. strcmp(s1, s2) - Returns 0 if s1 == s2, value < 0 if s1 < s2, or value > 0 if s1 > s3
        char x[10] = "hello";
        char y[10] = "help";
        
        // 'l' and 'p' chars determine order
        int c = strcmp(x, y);
        if (c == 0)
        	cout << "Strings are identical";
        else if (c < 0)
        	cout << x << " is before " << y;   // hello is before help
        else
        	cout << x << " is after " << y; 
        
      3. Uppercase letters have ASCII values smaller than lowercase letters
        char x[10] = "hello";
        char y[10] = "Help";
        
        // 'h' and 'H' chars determine order
        int c = strcmp(x, y);
        if (c == 0)
        	cout << "Strings are identical";
        else if (c < 0)
        	cout << x << " is before " << y;   
        else
        	cout << x << " is after " << y;   // hello is after Help