Functions: getline, get, and put in C++

The getline function can be used to read a string that includes whitespace characters and the get/put function can be used to read and write a single character

There is a problem in reading data using the stream extraction operator (>>). Data are delim­ited by whitespace. What happens if the whitespace characters are part of a string? In Sec­tion 4.8.4, “Reading Strings,” you learned how to use the getline function to read a string with whitespace. You can use the same function to read strings from a file. Recall that the syntax for the getline function is

getline(ifstream& input, int string s, char delimitChar)

The function stops reading characters when the delimiter character or end-of-file mark is encountered. If the delimiter is encountered, it is read but not stored in the array. The third argument delimitChar has a default value (‘\n’). The getline function is defined in the getline iostream header file.

Suppose a file named state.txt is created that contains the state names delimited by the pound (#) symbol. The following diagram shows the contents in the file:

Listing 13.6 gives a program that reads the states from the file.

Listing 13.6 ReadCity.cpp

1 #include <iostream>
2
#include <fstream>
3
#include <string>
4
using namespace std;
5
6
int main()
7 {
8     
// Open a file
9    ifstream input(“state.txt”);
10
11   
if (input.fail())

12   {
13       cout <<
“File does not exist” << endl;
14       cout <<
“Exit program” << endl;
15       
return 0;
16    }
17
18   
// Read data
19    string city;
20
21   
while (!input.eof()) // Continue if not end of file
22    {
23       getline(input, city,
‘#’);
24       cout << city << endl;
25    }
26
27    input.close();
28
29    cout <<
“Done” << endl;
30
31   
return 0;
32 }

Invoking getline(input, state, ‘#’) (line 23) reads characters to the array state until it encounters the # character or the end-of-file.

Two other useful functions are get and put. You can invoke the get function on an input object to read a character and invoke the put function on an output object to write a character. The get function has two versions:

char get() // Return a char

ifstream* get(char& ch) // Read a character to ch

The first version returns a character from the input. The second version passes a character reference argument, reads a character from the input, and stores it in ch. This function also returns the reference to the input object being used.

The header for the put function is

void put(char ch)

It writes the specified character to the output object.

Listing 13.7 gives an example of using these two functions. The program prompts the user to enter a file and copies it to a new file.

Listing 13.7 CopyFile.cpp

1 #include <iostream>
2
#include <fstream>
3
#include <string>
4
using namespace std;
5
6
int main()
7 {

8     // Enter a source file
9     cout << “Enter a source file name: “;
10    string inputFilename;
11    cin >> inputFilename;
12
13   
// Enter a target file
14    cout << “Enter a target file name: “;
15    string outputFilename;
16    cin >> outputFilename;
17
18   
// Create input and output streams
19    ifstream input(inputFilename.c_str());
20    ofstream output(outputFilename.c_str());
21
22   
if (input.fail())
23    {
24        cout << inputFilename <<
” does not exist” << endl;
25        cout <<
“Exit program” << endl;
26       
return 0;
27    }
28
29   
char ch = input.get();
30   
while (!input.eof()) // Continue if not end of file
31    {
32        output.put(ch);
33        ch = input.get();
// Read next character
34    }
35
36    input.close();
37    output.close();
38
39    cout <<
“\nCopy Done” << endl;
40
41   
return 0;
42 }

The program prompts the user to enter a source file name in line 11 and a target file name in line 16. An input object for inputFilename is created in line 19 and an output object for outputFilename in line 20. File names must be C-strings. inputFilename.c_str() returns a C-string from string inputFilename.

Lines 22-27 check whether the input file exists. Lines 30-34 read characters repeatedly one at a time using the get function and write the character to the output file using the put function.

Suppose lines 29-34 are replaced by the following code:

while (Hnput.eofO) // Continue if not end of file

{

output.put(input.get());

}

What will happen? If you run the program with this new code, you will see that the new file is one byte larger than the original one. The new file contains an extra garbage character at the end. This is because when the last character is read from the input file using input.get(), input.eof() is still false. Afterward, the program attempts to read another character; input.eof() now becomes true. However, the extraneous garbage character has already been sent to the output file.

The correct code in Listing 13.7 reads a character (line 29) and checks eof() (line 30). If eof() is true, the character is not put to output; otherwise, it is copied (line 32). This process continues until eof() returns true.

Source: Liang Y. Daniel (2013), Introduction to programming with C++, Pearson; 3rd edition.

Leave a Reply

Your email address will not be published. Required fields are marked *