Discussion 4-13

Homework Tips

  1. Don't try to code it all at once! Split the job into small managable parts. After each small part, run a few tests to make sure your code works.
    • For example, first write code that just does the input, then prints it back to the screen (unchanged).
    • Another suggestion for a small part: Compute the sum of all the money, but don't worry about formatting it correctly. (Example: 10 dollars and 192 cents)
  2. There are many different correct solutions. Don't worry if your code doesn't look like your friend's code. If your method works (and you are using material from our class), then good job! You have solved the problem.

Primitive Type: Char

Today we're going to learn all about strings! However, before we can do so we should at least understand a little about chars.

  1. char is a primitive type meant for storing a letter, number, or other special character (ex: 'a', '4', '$', etc.).
  2. chars are written in c++ using single quotes (strings are written using double quotes). Ex:
          char x = '(';
          char y = 'T';
          char z = ' ';  // A space counts as a character too
          string w = "r";
  3. The escape sequences we learned about earlier count as characters.
          char new_line = '\n';
          char quote_symbol = '\"';

You can cout variables of type char and it works as you would expect. For example:

#include<iostream>
using namespace std;

int main() {
   char x = '\n';
   char y = '\"';
   cout << y << "Gentlemen! You can't fight in here!" << x
        << "This is the war room!" << y << x;
   return 0;
}

Chars as integers: ascii codes

In computer memory, chars are actually stored as numbers. You can see what chars correspond to which numbers by looking at an ascii table

Converting between chars and ints is easy. You just type-cast (like we learned last time).

#include<iostream>
using namespace std;

int main() {
   int number = 65;
   cout << "My number is " << number << ".\n";
   cout << "This corresponds to the character " << (char)number << ".\n\n";

   char letter = 'r';
   cout << "My character is " << letter << ".\n";
   cout << "This corresponds to the number " << (int)letter << ".\n";

   // What do you think happens when we add chars together?
   cout << "Adding the chars '1' and '2' gives" << '1' + '2' << "\n";

   return 0;
}

Strings

A string is a C++ class that is made for storing a sequence of characters. The most common use of strings is to store words, phrases, sentences, etc. To use a string we need to include the string library. We initialize strings by using double-quotes. For example:

#include<iostream>
#include<string> 	// To use strings, we must include this library
using namespace std;

int main() {
   string output = "Hello World!\n";
   cout << output;
   return 0;
}

Representation as a sequence of characters

Suppose I write the line

string name = "Geoff Iyer";

Then the variable name is actually a sequence of 10 characters. They are numbered 0 to 9, and you can even refer to them individually.

name[0] // this is the G
name[1] // this is the e
...
name[8] // e
name[9] // r

// You can also use name.at(4) instead of name[4]. This has pretty much the same functionality.

You can use the [] notation to select out characters from your string:

#include<iostream>
#include<string>
using namespace std;

int main() {
   string word = "Aquarium";
   cout << "Please input an integer between 0 and 7: ";
   int pos;
   cin >> pos;
   
   cout << "My word is \"Aquarium\", and the character in position " << pos
        << " is " << word[pos] << ".\n";
   return 0;
}

You can even use this to edit the characters inside your string. For example:

#include<iostream>
#include<string>
using namespace std;

int main() {
   string word = "cat";
   cout << word << '\n';
   word[1] = 'o';
   cout << word << '\n';
   word[2] = 'g';
   cout << word << '\n';
   word[0] = 'd';
   cout << word << '\n';
   return 0;
}

Using getline to Input Strings

Next we're going talk about how to allow the user to input a string through the console. There's more than one way to do this, but our favorite way is through the getline function. The syntax is

   getline(cin, YOUR_STRING_HERE); /* Gets the next line from cin (up until the next \n)
                                      and stores it inside YOUR_STRING_HERE */

Here's an example:

#include<iostream>
#include<string>
using namespace std;

int main() {
	string someString;
	cout << "Please input your favorite color: \n";
	getline(cin, someString);
	cout << "Your favorite color is " << someString << ".\n";
	return 0;
}

Using cin to Input Strings (not as good as getline)

You can use cin to input strings. I don't recommend it, but I do want to talk about it for a little. If you use cin to input a string, it will grab the first word out of the cin buffer (up until a \n or a space). If the input contains more than one word, only the first word will be used, and the rest will be left in the cin buffer. Here's an example program:

#include <iostream>
#include <string>
using namespace std;

int main() {
    string firstString, secondString;
    cout << "Please input a string:\n";
    cin >> firstString;
    
    cout << "Please input another string:\n";
    cin >> secondString;
    
    cout << "\nHere are your two strings:\n";
    cout << firstString << endl << secondString << endl;
    return 0;
}

// Try running this code, and input a two-word (or more) phrase at the first prompt.
// What happens?
// Turns out stuff is getting stored in the cin buffer.

getline and cin don't work well together

Read through the following code and guess what it should do. Then run it and see what it actually does.

#include<iostream>
#include<string>
using namespace std;

int main() {
	int num;
	string word;
	cout << "Please input an integer: \n";
	cin >> num;
	cout << "Please input a word: \n";
	getline(cin, word);
	cout << "Your number was " << num << " and you word was " << word << ".\n";
	return 0;
}

You should notice that this program doesn't run as intended. It inputs an integer as expected, but it doesn't let you input a string. Instead it just skips to the end, and 'word' is just the empty string.

We're going to work through this line by line to try to explain what's going on.

#include<iostream>
#include<string>
using namespace std;

int main() {
    int num;
    string word;
    cout << "Please input an integer: \n";
    
    cin >> num;    /* Interesting stuff starts here:
            Suppose I input the number 123.
            What actually happens: cin takes in the input "123\n".
                (it takes in the 123 that you entered, as well as the endline that
                 you use)
            The line "cin >> num;" tells c++ to take the info from cin ("123\n") and store it 
            inside num. Since num is an int, it can only take integer values. So c++ will take
            the 123 from "123\n" and store it inside num. Then the "\n" will be left inside cin.*/


    cout << "Please input a word: \n";    // At this point the cin buffer contains "\n"

    getline(cin, word);    /* Here c++ sees that the cin buffer is not empty. So instead of allowing 
            you to give new input, it'll use what's current stored in cin. Well, right now cin
            contains "\n". The getline command takes in everything up to (but not including) the 
            "\n". So for this example, the getline will get nothing, and word will be empty.*/

    
    // At this point num == 123 and word == "", so that's what is output.

    cout << "Your number was " << num << " and you word was " << word << ".\n";
    return 0;
}

/* Stuff to try for funsies:
When the program asks you to input an integer, try putting in 12ASDLKA.
    What do you think will happen?
    What actually happens?
    Can you explain why?
*/

Fixing this problem using an extra getline

Here's one way to fix the problem:

#include<iostream>
#include<string>
using namespace std;

int main() {
    int num;
    string word;
    cout << "Please input an integer: \n";
    cin >> num;
    cout << "Please input a word: \n";
    
    getline(cin, word); // This getline will grab the '\n' character from the buffer

    getline(cin, word); // This getline will allow you to input what you want

    cout << "Your number was " << num << " and you word was " << word << ".\n";
    return 0;
}

Another way to fix the problem is to use the cin.ignore() function. If you're interested you can look this up online. Short explanation: using cin.ignore() clears one character from the cin buffer. You can use this to get rid of the '\n'.

Some Extra String-Functions

Each string comes with a bunch of functions that help you manipulate your data. We've already talked about using the 'string.at' function to access individual characters of your string. But there are a lot more things you can do. Below is a short list of the ones I find the most useful. For a complete list, check out the c++ reference page for string.

  1. The + operator for strings
    • You can concatenate strings using the + operator
    • Example:
              string str1 = "I want ";
              string str2 = "some pie!!";
              string final_string = str1 + str2;
              cout << final_string;
  2. string.size()
    • This function returns the number of characters in the string
    • For example:
              string myString = "Hello!";
              cout << myString.size();  // Prints 6
              myString = myString + "!!!!!!";
              cout << myString.size();  // Prints 12
            
  3. string.substr(unsigned begin, unsigned length)
    • This function returns a substring of your string. The substring will start at the position marked by begin, and will contain a number of characters equal to length.
    • Example:
              string myString = "I like turtles";
              string yourString = myString.substr(2,4);
              cout << yourString; // Prints 'like'
  4. string.find(string str)
    • This function searches your string for a substring equal to str. If it finds one then the function will return the starting position. If it doesn't find one then the function will return a value called string::npos
    • Example:
              string myString = "I like turtles";
              cout << myString.find("ike") << "\n"; // Prints 3
              cout << myString.find("rr") << "\n";  // What prints depends on your machine, 
                                                    // but it is equal to string::npos
    • Example #2:
              // What will this code segment do?
              string myString = "Xtreme Kool Letterz";
              int pos = myString.find("z");
              myString[pos] = 's';
      
              pos = myString.find("K");
              myString[pos] = 'C';
      
              pos = myString.find("X");
              myString[pos] = 'x';
              myString = "E" + myString;
        
  5. string.erase(unsigned pos, unsigned length)
    • This function erases a number of characters of your string. It starts at pos, and erases a total of length characters.
    • Example:
              string myString = "I like turtles";
              myString.erase(2,5);
              cout << myString << "\n";  // Prints "I turtles"

Note: A lot of these functions will do different things based on how many input arguments you give. For example, we can write

   string myString = "turtles";
   cout << myString.find("t", 2) << "\n";  // Prints 3
                           // The 2 tells the function to begin searching at position 2

   myString.erase(); // Erases the entire string
                     // In other words, it assumes you entered pos=0 and length=biggest possible number

Try experimenting around to find with different numbers of inputs to see what happens. Also, I'll write some practice problems involving using these functions soon enough.