Home‎ > ‎CS 11M‎ > ‎

Characters and Strings

Questions, Answers and Review

  • Questions from last class?
  • Questions about homework?

Characters and Strings

Type char

  • In addition to numbers, computers can manipulate text and other non-numerical types
  • Values of type char (short for character) are a single letter, number or special symbol
  • We specify a character by enclosing it in single quotes (")
    • The quote marks are not part of the data
  • For example:
    'a'   'b'   'Z'   '3'   'q'   '$'   '*'

ASCII Code

  • When we use a char data type, we store the character using a code known as ASCII
  • ASCII, which is an acronym for American Standard Code for Information Interchange, assigns a number to every character
  • Remember that computers store only numbers
  • So to handle text, each character is assigned a number as shown below
  • Each character requires 7-bits, which means it fits within one byte
  • ASCII was the first standardized code but is limited to English
  • However, ASCII has been extended to include all languages
  • The extended ASCII code is called Unicode

Table of ASCII Codes

ASCII table

Source: imageKB.com

Declaring and Assigning char Variables

  • As with other data types, we must declare char variables before use:
    char letterA;
  • We assign values to a char variable using the equals sign:
    letterA = 'A';
  • Just like numerical types, we can combine declaration and assignment into one statement:
    char letterB = 'B';
  • C++ allows us to assign ASCII code numbers to char variables as well
    char letterC = 67;
    char letterD = letterC + 1;
    

Example Code with char Variables

#include <ArduinoSTL.h>

using namespace std;

void setup() {
  Serial.begin(9600);
  char letterA;
  letterA = 'A';
  cout << letterA << endl;
  char letterB = 'B';
  cout << letterB << endl;
  char letterC = 67;
  cout << letterC << endl;
  char letterD = letterC + 1;
  cout << letterD << endl;
  cout << "Enter some characters" << endl;
}

void loop() {
  if (Serial.available()) {
    char code; 
    code = Serial.read();
    if (10 == code) {
      cout << "[Line Feed]" << endl;
    } else if (13 == code) {
      cout << "[Carriage Return]" << endl;
    } else {
      cout << code;
    }
  }
}

Serial I/O with Type char

  • Like numbers, we can output type char using cout
    char letter = 'A';
    cout << letterA << 'B';
    
  • Also, we can input type char using Serial.read()
        char letter = Serial.read();
        cout << letter;
  • Serial.read() works differently than cin
    • Serial.read() reads every character 
    • cin ignores whitespace:
      • Space
      • Tab
      • Newline
      • Carriage Return
Check Yourself
  1. The type of delimiter used to enclose single characters of type char is the ________.
  2. The correct data type for a single character is ________.
    1. character
    2. char
    3. text
    4. string
  3. Which of the following correctly declares a variable for a single character and assigns it a value?
    1. char var = 'z';
    2. char var = 122;
    3. char var = "z";
    4. char var = 'a' + 25;
  4. True or false: we can display a single ASCII character with cout?

More Information

  • ASCII: Video introduction from Harvard CS50.tv on YouTube

Introduction to Strings

  • In addition to single characters, computers can work with text strings
  • For example, in the following the characters between the double quotes are displayed as text:
    cout << "Hello World!";
    
  • Programmers refer to text like this as a string because it is composed of a sequence of characters that we string together
  • Strings are enclosed in double quotes, which are not part of the string
  • For example:
    "Hello"  "b"  "3.14159"  "$3.95"  "My name is Mike"
  • Notice that the string "3.14159" could be expressed as a double by removing the quotes
  • However, a computer stores these two values very differently and we must use them in different ways
  • For instance, we cannot multiply the "3.14159" by 2, but we can when it is expressed as a double:
    double twopi = "3.14159" * 2; // NO!
    double twopi = 3.14159 * 2; // Okay
    

String Variables and Serial I/O

  • We declare and assign values to String variables like numeric and character types
  • For example:
      string firstName; 
      firstName = "Oscar"; 
      string lastName = "Mayer"; 
      cout << firstName << " " << lastName << endl;

Serial I/O with Strings

  • Like numbers and characters, we can output type string using cout and input strings using cin.
  • Input using cin breaks at whitespace characters 
    • \t - Tab
    • \r - Carriage Return
    • \n - Newline
    • Space
  • The getline() function returns a string with all text until a newline.
    • The string may contain spaces

Example of Serial I/O with Strings

#include <ArduinoSTL.h>

using namespace std;

void setup() {
  Serial.begin(9600);
  cout << "Enter your name." << endl;
}

void loop() {
  string name; 
  getline(cin, name); 
  cout << "You entered: " << name << endl;
}

Check Yourself
  1. True or false: use a string variable rather than a char variable when you need to store more than one character.
  2. The type of delimiters used to enclose strings is the ________
  3. True or false: "A" and 'A' are the same.
  4. True or false: we can perform arithmetic operations on strings.
  5. Which of the following is the correct way to declare a string variable named mystring and assign it the text "Hi Mom!"?
    1. string myString = Hi Mom!;
    2. string myString = "Hi Mom!";
    3. String myString = "Hi Mom!";
    4. String myString = "Hi Mom"!

More Information

  • Arduino has its own string class. It's called String and it's similar to C++'s built in string class

Output of Hard-to-Print Characters

  • We have been using cout to output strings
  • However, some strings are more difficult to output than others
  • For example, what if we wanted to output : "Say, Hey!"
  • We could write a statement like:
    cout << "Say, "Hey!"";
    
  • How would the compiler treat the double-quote marks (") in the statement?
  • Some characters cannot be output directly in a string
  • Also, the first 32 ASCII characters are old Teleprinter control characters
  • Some control characters are still used today such as newline characters
  • We need some way to output characters like control codes and double quotes (")

Escape Sequences

  • C++ can print control codes and some hard-to-print characters using escape sequences
  • A backslash (\) directly in front of some characters tell the compiler to escape from the normal interpretation
  • The following table lists some common nonprinting and hard-to-print characters supported by the Serial Monitor
Sequence Meaning
\n New line
\t Horizontal tab
\\ Backslash
\' Single quote
\" Double quote
\ooo ASCII character in octal notation
\xhhh ASCII character in hexadecimal notation

Examples of Escape Sequences Supported by the Serial Monitor

#include <ArduinoSTL.h>

using namespace std;

void setup() {
  Serial.begin(9600);
  cout << "Say, \"Hey!\"" << endl;
  cout << "one\ntwo\x00Athree" << endl;
  cout << "Left\tRight" << endl;
}

void loop() {
}

Check Yourself
  1. True or false: an escape sequence is a series of characters that does not represent itself but is translated into a character code.
  2. Which of the following is an escape sequence?
    1. "/n"
    2. "/t/n/t"
    3. "\n\t\""
    4. "/\n"
  3. Which of the following is a correct way to print: Say, "Hey"!?
    1. cout << "Say, "Hey!"";
    2. cout << \"Say, "Hey!"\";
    3. cout << "Say, \"Hey!\"";
    4. cout << "Say, \"Hey!"\";

Joining Strings (Concatenation)

  • We can join strings together in a variety of ways
  • The join operation is called concatenation
  • We join two strings together using the '+' operator
  • We can concatenate a string variable with:
    • Another string variable
    • A literal string in double quotes like "abc"
    • A literal char like 'a' or a char variable
    • A literal integer like 123 or an integer variable

Examples of Concatenation

  • We can join a String variable with another, like:
      string s1 = "Hello", s2 = "World!";
      string s3 = s1 + s2;
      cout << s3;
    
  • The String s3 now has the contents of both s1 and s2
  • We can also mix String variables and literal strings:
      string s1 = "Hello", s2 = "World!";
      string s3 = s1 + ", " + s2;
      cout << s3;
    
  • The thing on the left of the + must be a string variable
  • For instance, the following will NOT work:
    string greeting = "Hello" + " " + "World!"; // No!
    
  • However, this is not usually a problem because we can just make one long literal string:
    string greeting = "Hello World!"; // Okay
    string greeting = string("Hello") + " " + "World!"; // Okay 
  • In addition, we can concatenate strings and characters:
      char letter = 'A';
      string s5 = "BC";
      s5 = letter + s5 + 'D';
      cout << s5;
  • C++ does not let us join a string with a number, like:
    
        string s6 = s5 + 123;

Appending Strings

  • Notice that we can append a string to a String variable
  • For example, we can add one string to the end of another using +=:
      string s9 = "Hello";
      s9 += " World";
      cout << s9;
    
  • Appending can be useful when building up strings containing text and numbers from various sources

Check Yourself

  1. The operator used to join two strings is ________.
  2. The value of s3 after the following code executes is ________.
    string s1 = "Hi ", s2 = "Mom!";
    string s3 = s1 + s2;
    
  3. The result of trying to compile and run the following code is ________.
    string s1 = "Hi", s2 = "Mom!";
    string s3 = s1 + " " + s2;
    
  4. The result of trying to compile and run the following code is ________.
    string s1 = "Hi " + " " + "Mom!";
    

String Functions

  • Strings are a special type of variable called objects, which we will study in more detail later in the course
  • An object is a data type that can have functions associated with it
  • These functions are called member functions and are called using dot notation
  • The syntax for calling a member function of a string object is:
    stringName.functionName(arguments)
    
  • Where:
    • stringName: the name of the string variable
    • functionName: the name of the member function
    • arguments: the input values, if any
  • Once we create a string variable, we call (invoke) its member functions

Some Commonly-Used String Functions

  • C/C++ supports many string functions (see documentation)
  • We cover a few commonly used string functions in this section
  • length(): Returns the number of characters in a string
    string msg = "The number of characters is: ";     cout << msg << msg.length(); 
substring(from, length) Returns a substring starting at index from containing length characters.
  • For example, we extract the first 4 letters of a string:
    string greeting = "Hello, World!\n";
    string sub = greeting.substr(0, 4);
    
  • Similarly, we extract characters 7 to 12, but not including 12:
    sub += greeting.substr(7, 6);
    
    H e l l o ,
    W o r l d ! \n
    0 1 2 3 4 5 6 7 8 9 10 11 12 13
  • When finished, we print the message we extracted with substr():
    cout << sub;
  • If you leave the length off substr() returns a substring starting at from until the end of the string 

    string greeting = "Hello, World!\n";
    string sub = greeting.substr(7);

Example Code Calling String Member Functions

#include <ArduinoSTL.h>

using namespace std;

void setup() {
  Serial.begin(9600);
  cout << "Enter a string";
}

void loop() {
  // Demonstrate input
  string inStr;
  getline(cin, inStr);
  cout << "For the string \"" << inStr << "\"" << endl;

  // Demonstrate substring()
  string greeting = "Hello, World!";
  cout << "For the greeting: " << greeting << endl;
  string sub = greeting.substr(0, 4);
  sub += greeting.substr(7); // position 4 to the end..
  cout << "The substring greeting is: " << sub << endl;
}

Check Yourself

  1. True or false: an object is a data type that can have functions associated with it.
  2. To call a function that is part of an object, between the object name and the function name we code a ________.
  3. The following code displays ________.
    String message = "Hi mom!";
    Serial.println(message.length());
    
    1. 2
    2. 6
    3. 7
    4. "Hi mom!"
  4. For the following string variable, the function call that extracts "mom" is ________.
    String message = "Hi mom!";
    
    1. message.substring(3, 6)
    2. message.substring(2, 6)
    3. message.substring(3, 5)
    4. message.substring(2, 5)

Comparing Characters and Strings

  • Character data can be evaluated using relational operators
  • Relational operators are useful for making alphabetic comparison between characters, like:
    if ('A' < 'B')
    
  • Since C++ stores characters as numbers using ASCII codes, the computer is actually comparing numbers
  • Remember that letters nearer to the start of the alphabet have lower numerical values than later letters
  • Thus a numerical comparison can decide the alphabetical order of characters

Comparing Strings

  • We can compare strings using relational operators as well
  • C++ compares two strings using lexicographical order (a.k.a. alphabetical order)
  • Lexicographical order means the comparison is based on the alphabetical order of component letters
  • For example, "car" is less than "cat":
    c a r
    c a t
  • Also, "car" is less than "card"
    c a r
    c a r d
  • We can test string comparisons in the following example program

Example Program Comparing Strings

#include <ArduinoSTL.h>

using namespace std;

void setup() {
  Serial.begin(9600);
  string s1 = "cat"; 
  string s2 = "dog"; 

  if (s1 == s2) {
    cout << "The strings are equal." << endl;
  }
  else if (s1 < s2) {
    cout << "s1 < s2" << endl;
  }
  else {
    cout << "s1 > s2" << endl;
  }
}

void loop() {
}

Check Yourself

  1. The result of evaluating the following relational expression is ________.
    'A' < 'B'
  2. The result of evaluating the following relational expression is ________.
    "A" < "B"
  3. Of the following pairs of strings, which comes first in lexicographic order for each of them?
    1. "Harry", "Potter"
    2. "Harry", "Hairy"
    3. "car", "C++"
    4. "car model", "carburetor"

More Information

Exercise 1: Initials 

In this exercise we write an interactive program using strings that runs like this:

Enter your first name: Mick
Enter your last name: Shrimpton
Welcome "Mick Shrimpton"!
Your initials: MS
Enter your first name: (so you can start over)

Note that the underlined font shows what is typed by the user in the text field at the top of the window. As you work through the exercise, I suggest that you compile after each step so you know where an error is located if you make a mistake. Also, if you get stuck then ask a classmate or the instructor for help.

Parts

  • Arduino board
  • USB cable

Starter Code

#include <ArduinoSTL.h> using namespace std; string firstName = ""; string lastName = ""; void setup() { Serial.begin(9600); } void loop() { // put your code here }

Specifications

  1. Start the Arduino IDE, copy the starter code above and paste it into the main IDE window.
  2. Save the project using the name initials.ino (File > Save As...) to a convenient location like the Desktop or the Arduino projects folder.
  3. Compile the sketch to verify you copied the starter code correctly.

    When compiling is successful, you will see a message at the bottom of the source code window saying, "Done compiling."

  4. Where shown by the comment, add a statement to read a string from the serial port and save it in a string variable
  5. Extract the first letter of the first and last names using substr() like:

    string initials = firstName.substr(0, 1);
    initials += lastName.substr(0, 1);

  6. Next print the welcome message followed by printing the initials, like:
    string sp = "Welcome \"";
    cout << sp << firstName << " " << lastName << "\"!" << endl;
    cout << "Your initials are: " << initials << endl;
    
  7. Compile and upload your code to verify it works correctly.
  8. You should now be able to see it work like the example shown at the start. If you have problems, ask a classmate or the instructor for help.
  9. Verify your code with the example shown below. Your code does not need to be the same but comparing helps understand other ways of coding.
  10. Save your initials.ino file to submit to Canvas with the next homework.

When finished, please help those around you.

Summary

  • A character is a letter, number or special symbol
  • We make character literals by enclosing a single character in single quotes
  • We declare character variables using char as the data type:
    char letter = 'A';
    
  • Each character is stored as a number, using its ASCII code
  • We can input and output char data to the Serial Monitor like:
    char letter = Serial.read(); // input
    cin >> letter; // input
    cout << letter; // output
    
  • We make string literals by enclosing characters in double quotes
  • We declare string variables using String as the data type:
    string s1 = "Hello Mom!";
  • To concatenate two strings, use the "+" operator:
    string s2 = s1 + " suffix";
  • Type string can be input and output with the Serial Monitor
  • We use functions of the string object for some operations
  • We looked at the member functions:
    • length(): Returns the number of characters in a string
      string s = "Hello";
      Serial.println(s.length());
      
    • substr(from, length): Returns a substring starting at index from and ending just before to
    • string greeting = "Hello, World!\n";
      string sub = greeting.substr(0, 4);
  • We can use these relational operators with characters and strings
  • Relational operators are useful for making alphabetic comparisons

Wrap Up and Reminders

  • When class is over, please shut down your computer.
  • Complete unfinished exercises from today before the next class meeting
Comments