What We Will Cover
Continuations
Homework Questions?
Questions from last class?
A programmer wants to create an application that allows employees to log hours in a user interface. Which of the following will be the first step in coding this application?
- design the classes
- prototype the user interface
- deploy the application
- analyze the current procedure for logging hours
^ top
11.1: Using C-Strings
Objectives
At the end of the lesson the student will be able to:
- Initialize C-strings
- Use C-string library functions
- Perform I/O on C-strings
- Convert C-strings to numbers
|
^ top
11.1.1: About C-Strings
- Previously we discussed arrays, including arrays of type
char
- C++ offers a special kind of
char array known as a C-string
- Inherited from the C programming language
- Each
char is stored in the array with a special null character '\0' ending the string
- The null character is a single character
- For example, a
char-array of 10 used to store a C-string:

^ top
11.1.2: Declaring and Initializing C-Strings
char arrayName[MaximumCStringSize + 1];
The "+ 1" reserves the additional space needed by '\0'
For example:
char s[10] = "Hi Mom!";
cout << s << endl;
Note that declaring a C-string as char s[10] creates room for only 9 char's
- The null character terminator requires one space
The size variable is actually optional for a C-string
For example:
char shortString[] = "abc";
cout << shortString << endl;
This will create a C-string of size 4 terminated with a '\0'
What is wrong with the following declaration?
char shortString[] = {'a', 'b', 'c'};
cout << shortString << endl;
^ top
11.1.3: Iterating C-Strings
- You can iterate a C-string like you do an array
- For example:
const int SIZE = 10;
char shortString[SIZE] = "Hi Mom!";
int index = 0;
while (shortString[index] != '\0') {
shortString[index] = 'X';
index++;
}
cout << shortString << endl;
You must be careful not to replace the null character ('\0')
If the null character is lost, the array cannot act like a C-string
What could you change to still process the array correctly in case the null character was missing?
^ top
11.1.4: Using C-String Library Functions
- Note that the following statement produces a compiler error:
char aString[11];
aString = "Hello";
The assignment operator does not work with C-strings
Instead, programmers often use library function strcpy() to assign characters
- Defined in the
cstring library
- Included automatically by our compiler
For example:
char aString[11];
strcpy (aString, "Hi Mom!");
cout << aString << endl;
Function strcpy() automatically appends the '\0' character to the C-string
Note that strcpy() does not know the length of the first char array
Thus, strcpy() can write characters beyond the declared size of the array
Many versions of C++ have a safer version of strcpy() named strncpy()
strncpy() uses a third argument for the maximum number of char's to copy
For example:
char anotherString[10];
strncpy(anotherString, aString, 9);
cout << anotherString << endl;
Copies up to 9 characters into another_string, leaving one space for '\0'
- However, it does not put the
'\0' in the array if it stops copying before the end of the string
The == operator does not work as you might expect with C-strings
- You only compare the base address of the two arrays
Instead, programmers use strcmp() to compare the content of C-strings
For example:
#include <cstring>
if (strcmp(cString1, cString2)) {
cout << "Strings are not the same.";
} else {
cout << "String are the same.";
}
strcmp() compares the char codes in the two C-strings one char at a time
As soon as the characters do not match:
- Returns a negative value if the code in the first parameter is less
- Returns a positive value if the code in the second parameter is less
If the two C-strings are the same, strcmp() returns 0
strlen() is another cstring library function that returns the number of characters in a string
int x = strlen(aString);
strcat() concatenates two C-strings
- The second argument is added to the end of the first
- The result is placed in the first argument
For example:
char stringVar[20] = "The rain";
strcat(stringVar, "in Spain");
Now string_var contains "The rainin Spain"
strncat() is a safer version of strcat()
- A third parameter limits the number of characters to concatenate
For example:
char string_var[20] = "The rain";
strncat(string_var, "in Spain", 11);
Further Information
^ top
11.1.5: C-Strings as Arguments and Parameters
- C-string variables are arrays
- C-string arguments and parameters are used just like arrays
- Like other arrays, be careful with the array size
- If a function changes the value of a C-string parameter
- Best to include a parameter for the declared size of the C-string
- If a function does not change the value of a C-string parameter
- You can use the null character to detect the end of the string
- No size argument is needed
^ top
11.1.6: Performing I/O on C-Strings
- C-strings can be output with the insertion << operator
- For example:
char news[] = "C-strings";
cout << news << " Wow." << endl;
The extraction operator >> can fill a C-string
For example:
char a[80], b[80];
cout << "Enter input: " << endl;
cin >> a >> b;
cout << a << b << "End of Output";
Note that whitespace ends reading of the data
To read an entire line you can use function getline() of the object cin
Syntax:
cin.getline(cString, maxSize + 1);
cin.getline() has two arguments
- The first is a C-string variable to store input data
- The second specifies the maximum number of
char's to read
For example:
char line[80];
cout << "Enter a line of input:\n";
cin.getline(line, 80);
cout << line << "END OF OUTPUT\n";
cin.getline() stops reading after the maximum number of char's - 1 is read
- one character is reserved for the null character
cin.getline() stops even if the end of the line has not been reached
C-string input and output works the same way with file streams
inStream >> cString;
inStream.getline(cString, 80);
Similarly, you can use an output file stream like you use cout
outStream << cString;
^ top
11.1.7: Converting C-Strings to Numbers
- "1234" is a string of characters
- 1234 is a number
- Sometimes you need to convert C-strings to numbers
- For instance, you may need to read string data because:
- Reading money may involve a dollar sign
- Reading percentages may involve a percent sign
- To read numbers as characters:
- Read input as characters into a C-string
- Remove unwanted characters
- Use a conversion function to convert the C-string to a numeric value
- The conversion functions are found in the library
cstdlib
- To use the functions use the include directive
#include <cstdlib>
The most used functions: atoi(), atol() and atof()
Function atoi() to converts a C-string to an int value
int x = atoi("1234"); // returns 1234
int x = atoi("#1234"); // returns 0 because # is not a digit
Function atol() to converts a C-string to a long value
long y = atol("1234"); // returns 1234 as a long
Function atof() to converts a C-string to a double value
double z = atof("9.99"); // returns 9.99
double w = atof("$9.99"); // returns 0.0 because $
// is not a digit
^ top
11.1.8: Summary
- C++ offers a special kind of
char array known as a C-string
- Has the same shortcoming as arrays
- You need to know about C-Strings because you often have to work with them
- Each
char is stored in the array with a special null character '\0' ending the string
- Syntax:
char ArrayName[MaximumCStringSize + 1];
You can iterate a C-string like an array
int index = 0;
while (ourString[index] != '\0' && index < SIZE) {
ourString[index] = 'X';
index++;
}
To assign C-strings, use the cstring library function strcpy()
- A safer version of
strcpy() is named strncpy()
Programmers use strcmp() to compare the contents of C-strings
strlen() returns the number of characters in a string
strcat() concatenates two C-strings
strncat() is a safer version of strcat()
C-string variables are arrays
C-string arguments and parameters are used just like arrays
C-strings can be output with the insertion << operator
The extraction operator >> can fill a C-string
To read an entire line you can use function cin.getline()
Syntax:
cin.getline(cString, maxSize + 1);
To convert C-strings to numbers, use a conversion function
- Function
atoi() to converts a C-string to an int value
- Function
atol() to converts a C-string to a long value
- Function
atof() to converts a C-string to a double value
^ top
Exercise 11.1
Specifications
- Write a program named
readcstr.cpp that reads a line of text as a C-string and prints the line vertically (one character at a time) down the page
- As a comment in your code, answer the following question:
Q1: How large should you make the C-string? Why?
- Submit your source code as the answer to this exercise.
^ top
11.2: String Class
Objectives
At the end of the lesson the student will be able to:
- Use
string constructors and member functions
|
^ top
11.2.1: Using Strings: A Review
- The
string class allows a programmer to use strings as a basic data type
- Defined in the string library and standard namespace
#include <string>
using namespace std;
Included automatically with our version of g++
Strings are stored in a character sequence starting at 0 (zero)

String variables and expressions are treated much like simple types
You can assign C-strings to string objects using the assignment operator
string s1 = "Hello Mom!";
Also, you can assign string objects to a string object
string s1, s2, s3;
s1 = "Hello "; // assignment
s2 = "Mom!";
s3 = s1 + s2; // concatenation
cout << s3 << endl;
Will the following code compile and run? Why or why not?
string s = "abc" + "def";
Comparison operators work with string objects
== returns true if two string objects contain the same characters in the same order
For example:
string s1, s2;
s1 = "Hello Mom!";
s2 = s1;
cout << (s1 == s2);
<, >, <=, >= can be used to compare string objects as well
^ top
11.2.2: Constructors of Class string
- Since
string is a class type, it has constructors
- The default
string constructor initializes the string to the empty string
string phrase; // empty string
Another string constructor takes a C-string argument
string noun("ants");
cout << noun << endl;
^ top
11.2.3: Indexing a String
- You can access any individual character of a string object using
[ ]
- For example:
string line;
cout << "Enter your name: ";
getline(cin, line);
cout << "The first letter is: " << line[0] << endl;
What happens if we try to display line[100]?
- Buffer overflow is a major source of errors and security flaws
Member function at accesses an individual character as well
cout << "The first letter is: "
<< line.at(0) << endl;
However, at checks for valid index values
When an invalid index is found, the program provides an error message and aborts
For example:
cout << "The first letter is: "
<< line.at(100) << endl;
Produces a message like:
5 [sig] fiddle 2272 open_stackdumpfile: Dumping stack trace to fiddle.exe.
stackdump
Which is better: An error message or a security flaw?
Further Information
^ top
11.2.4: Iterating Strings
- Member function length() returns the number of characters in the string object
string s = "abcdef";
unsigned n = s.length();
After we know the length, it is easy to iterate through the individual characters of a string
string s = "abcdef";
for (unsigned i = 0; i < s.length(); i++) {
cout << "Char[" << i << "]: " << s.at(i) << endl;
}
^ top
11.2.5: Finding Substrings
- Sometimes you want to know if a
string contains a certain word
- For this you can use the
find() member function
- Syntax:
unsigned int haystack.find(needle)
Searches for the string or char needle in the string haystack
Returns the index of the first occurrence of needle or string::npos if not found
For example
string str = "Do you want to play again?";
unsigned n = str.find("you");
if (n == string::npos) {
cout << "Could not find \"you\" in the str\n";
} else {
cout << "We found \"you\" in the str\n";
}
^ top
11.2.6: Erasing and Inserting Substrings
- Sometimes you want to erase or insert parts of a string
- To erase parts of a string, you can use the
erase() member function
- Syntax:
str.erase(start, length)
str.erase(start)
The first line removes all the characters between start and start + length
The second line removes all the characters from start through the end of the string
To insert characters into a string, use the insert() member function
Syntax:
str.insert(start, newStr)
Inserts the string newStr starting at position start
For Example
string str("Game over");
cout << str << endl;
str.erase(4, 5);
cout << str << endl;
str.insert(0, "I'm ");
cout << str << endl;
^ top
11.2.7: Summary
- The
string class allows the programmer to use strings like a primitive type
- Strings are stored in a character sequence starting at 0 (zero)

- You can construct
string objects like other class types
string noun("ants");
You can also assign C-strings to strings using the assignment operator
string s1 = "Hello Mom!";
You can concatenate (join) strings with the '+' operator
string s3 = s1 + " " + s2;
Comparison operators work with strings: ==, !=, <, >, <=, >=
You can access individual characters of a string using [] or member function at
You should use member function at because it checks for valid index values
line.at(0);
You can iterate through a string using a loop and the length() member function
string s = "abcdef";
for (unsigned i = 0; i < s.length(); i++) {
cout << "Char[" << i << "]: " << s.at(i) << endl;
}
You can find characters in a string using the find() member function
string str = "Do you want to play again?";
unsigned n = str.find("you");
You can erase and insert characters in a string as well
string str("Game over");
cout << str << endl;
str.erase(4, 5);
cout << str << endl;
str.insert(0, "I'm ");
cout << str << endl;
^ top
Exercise 11.2
Specifications
- Write a program named
triplex.cpp that replaces every third letter of a string with an 'X'.
- Submit your source code as the answer to this exercise.
^ top
11.3: Handling String Input
Objectives
At the end of the lesson the student will be able to:
- Use
getline() as a substitute for cin
|
^ top
11.3.1: Problems With cin
- To get input from a user, we have been using
cin
- However,
cin has a number of shortcomings
- When entering input into a string, a space causes the input to stop reading
- If a user enters a character when a number is expected, unpredictable results occur
For Example
#include <iostream>
using namespace std;
const int MAX = 20;
int main() {
int numItems;
string items[MAX];
cout << "Enter the number of items: ";
cin >> numItems;
for (int i = 0; i < numItems && i < MAX; i++) {
cout << "Enter item #" << i << ": ";
cin >> items[i];
}
cout << "You entered:\n";
for (int i = 0; i < numItems; i++) {
cout << i << ": " << items[i] << endl;
}
return 0;
}
- If you enter a letter, like 'A', for the number of items you get unpredictable results
- Also, if you enter items with whitespace between the words, the second word ends up in the wrong variable
- The reason for this is the way cin operates
- Recall that
cin >> numItems:
- Skips whitespace
- Reads characters
- Stops reading when the first unusable character is found
- This leaves the variable
numItems uninitialized in the first case
- In the second case, the string input stops whenever whitespace is encountered
^ top
11.3.2: Using getline()
- Our solution to the first problem was to use
getline()
getline(cin, items[i]);
This works because getline() reads until it encounters a '\n'
It turns out that a solution to the second problem uses getline() as well
Using getline() to Input Numbers
- To use
getline() to read numbers, we use the following algorithm:
- Read the input as a string using
getline()
- Convert the string to a number
^ top
11.3.3: Converting to Numbers
- To convert strings to numbers, we can use functions from
cstdlib
- These functions take a C-string parameter, so you must convert a
string to a C-String using the c_str() function
- For example:
double z = 0.0;
string text = "9.99";
z = atof(text.c_str());
cout << (z + 1 ) << endl;
Functions to Convert C-Strings to Numbers
Examples Converting Strings to Numbers
Using function atoi():
string s1 = "1234";
int x;
x = atoi(s1.c_str()); // returns 1234
cout << x << endl;
s1 = "#1234";
x = atoi(s1.c_str()); // returns 0 because # is not a digit
cout << x << endl;
Using function atol():
string s2 = "1234";
long y = atol(s2.c_str()); // returns 1234 as a long
cout << y << endl;
Using function atof():
string s3 = "9.99";
double z = 0.0;
z = atof(s3.c_str()); // returns 9.99
cout << z << endl;
s3 = "$9.99";
z = atof(s3.c_str()); // returns 0 because $ is not a digit
cout << z << endl;
^ top
11.3.4: Checking for Errors
- Note that some of the example shown above do not return the desire results
- For example, if the user enters
"$9.99", the function atof() returns 0
- To prevent this problem, we must check for erroneous characters
- To check, we iterate through every character of the input string and verify they are valid
- The valid characters for a positive double are: '0' - '9' and '.'
- Ignoring exponential notation
- In addition, we must verify that the user entered some number
- Otherwise, we get an empty string (
"")
Example of Verifying User Input When Using getline()
#include <iostream>
using namespace std;
const int MAX = 20;
int main() {
string input;
double value = 0;
bool error = true;
while (error == true) {
cout << "Enter a number: ";
getline(cin, input);
error = false;
for (unsigned i = 0; i < input.length(); i++) {
char ch = input.at(i);
if (ch != '.' && ch < '0' || ch > '9') {
error = true;
cout << "You must enter a numeric value\n";
}
}
}
value = atof(input.c_str());
cout << "You entered: " << value << endl;
return 0;
}
- Note that the verification loop does not catch all possible errors
- What other input errors might we want to check for?
^ top
11.3.5: No More cin
- We can use our
getline() + verification code to replace cin
- To make it easier to reuse the code, we wrap the code in a function
cin Replacement Function for Entering Positive doubles
#include <iostream>
using namespace std;
const int MAX = 20;
double inputDouble(string prompt);
int main() {
string input;
double value = inputDouble("Enter a positive number: ");
cout << "You entered: " << value << endl;
return 0;
}
double inputDouble(string prompt) {
string input;
double value = 0;
bool error = true;
while (error == true) {
cout << prompt;
getline(cin, input);
error = false;
for (unsigned i = 0; i < input.length(); i++) {
char ch = input.at(i);
if (ch != '.' && ch < '0' || ch > '9') {
error = true;
cout << "You must enter a numeric value\n";
break;
}
}
}
value = atof(input.c_str());
return value;
}
^ top
11.3.6: Summary
cin is useful for getting user input, but has a number of shortcomings
- For example: entering letters when expecting numbers
- We can design improved input functions using the
getline() function
- The algorithm we use is:
- Get user input using
getline()
- Check for unwanted characters
- Loop until the user enters only correct characters
- Use a conversion function to convert the string to a numeric value
^ top
Exercise 11.3
- Write a program named
inputint.cpp that uses getline() to read integer values.
- Use the code below to get started.
- Submit your source code as the answer to this exercise.
#include <iostream>
using namespace std;
const int MAX = 20;
double inputDouble(string prompt);
int main() {
string input;
double value = inputDouble("Enter a positive number: ");
cout << "You entered: " << value << endl;
return 0;
}
double inputDouble(string prompt) {
string input;
double value = 0;
bool error = true;
while (error == true) {
cout << prompt;
getline(cin, input);
error = false;
for (unsigned i = 0; i < input.length(); i++) {
char ch = input.at(i);
if (ch != '.' && ch < '0' || ch > '9') {
error = true;
cout << "You must enter a numeric value\n";
break;
}
}
}
value = atof(input.c_str());
return value;
}
^ top
Wrap Up
^ top
Home
| WebCT
| Announcements
| Day Schedule
| Eve Schedule
Course info
| Help
| FAQ's
| HowTo's
| Links
Last Updated: December 04 2004 @14:37:29
|