string
Class InputAnother useful thing to know about a class is what input options are available. For C-style strings, recall, you have three options:
char info[100];
cin >> info; // read a word
cin.getline(info, 100); // read a line, discard
cin.get(info, 100); // read a line, leave
in queue
For string
objects, recall, you have two options:
string stuff;
cin >> stuff; // read a word
getline(cin, stuff); // read a line, discard
Both versions of getline()
allow for an optional argument that specifies which character to use to delimit input:
cin.getline(info,100,':'), // read up to :, discard :
getline(stuff, ':'), // read up to :, discard :
The main operational difference is that the string
versions automatically size the target string
object to hold the input characters:
char fname[10];
string lname;
cin >> fname; // could be a problem if input size > 9 characters
cin >> lname; // can read a very, very long word
cin.getline(fname, 10); // may truncate input
getline(cin, fname); // no truncation
The automatic sizing feature allows the string
version of getline()
to dispense with the numeric parameter that limits the number of input characters to be read.
A design difference is that the C-style string input facilities are methods of the istream
class, whereas the string
versions are standalone functions. That’s why cin
is an invoking object for C-style string input and a function argument for string
object input. This applies to the >>
form, too, which is evident if the code is written in function form:
cin.operator>>(fname); // ostream class method
operator>>(cin, lname); // regular function
Let’s examine the string
input functions a bit more closely. Both, as mentioned, size the target string to fit the input. There are limits. The first limiting factor is the maximum allowable size for a string, represented by the constant string::npos
. This, typically, is the maximum value of an unsigned int
, so it doesn’t pose a practical limit for ordinary, interactive input. It could be a factor, however, if you attempt to read the contents of an entire file into a single string
object. The second limiting factor is the amount of memory available to a program.
The getline()
function for the string
class reads characters from the input and stores them in a string
object until one of three things occurs:
• The end-of-file is encountered, in which case eofbit
of the input stream is set, implying that both the fail()
and eof()
methods will return true
.
• The delimiting character (
, by default) is reached, in which case it is removed from the input stream but not stored.
• The maximum possible number of characters (the lesser of string::npos
and the number of bytes in memory available for allocation) is read, in which case failbit
of the input stream is set, implying that the fail()
method will return true
.
(An input stream object has an accounting system to keep track of the error state of the stream. In this system, setting eofbit
registers detecting the end-of-file; setting failbit
registers detecting an input error; setting badbit
registers some unrecognized failure, such as a hardware failure; and setting goodbit
indicates that all is well. Chapter 17, “Input, Output, and Files,” discusses this further.)
The operator>>()
function for the string
class behaves similarly, except that instead of reading to and discarding a delimiting character, it reads up to a white space character and leaves that character in the input queue. A white space character is a space, newline, or tab character or more generally, any character for which isspace()
returns true
.
So far in this book, you’ve seen several examples of console string
input. Because the input functions for string
objects work with streams and recognize the end-of-file, you can also use them for file input. Listing 16.2 shows a short example that reads strings from the file. It assumes that the file contains strings separated by the colon character and uses the getline()
method of specifying a delimiter. It then numbers and displays the strings, one string to an output line.
// strfile.cpp -- read strings from a file
#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>
int main()
{
using namespace std;
ifstream fin;
fin.open("tobuy.txt");
if (fin.is_open() == false)
{
cerr << "Can't open file. Bye.
";
exit(EXIT_FAILURE);
}
string item;
int count = 0;
getline(fin, item, ':'),
while (fin) // while input is good
{
++count;
cout << count <<": " << item << endl;
getline(fin, item,':'),
}
cout << "Done
";
fin.close();
return 0;
}
Here is a sample tobuy.txt
file:
sardines:chocolate ice cream:pop corn:leeks:
cottage cheese:olive oil:butter:tofu:
Typically, for the program to find the text file, the text file should be in the same directory as the executable program or sometimes in the same directory as the project file. Or you can provide the full path name. On a Windows system, keep in mind that in a C-style string the escape sequence \
represents a single backslash:
fin.open("C:\CPP\Progs\tobuy.txt"); // file = C:CPPProgs obuy.txt
Here is the output of the program in Listing 16.2:
1: sardines
2: chocolate ice cream
3: pop corn
4: leeks
5:
cottage cheese
6: olive oil
7: butter
8: tofu
9:
Done
Note that with :
specified as the delimiting character, the newline character becomes just another regular character. Thus, the newline character at the end of the first line of the file becomes the first character of the string that continues as "cottage cheese"
. Similarly, the newline character at the end of the second input line, if present, becomes the sole content of the ninth input string.
3.138.36.38