0% found this document useful (0 votes)
22 views38 pages

Lec14 Io

Uploaded by

Mamat Rahmat
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
22 views38 pages

Lec14 Io

Uploaded by

Mamat Rahmat
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 38

CSCI1540

Fundamental Computing
with C++
Stream I/O and File I/O

Fall, 2024
Outline
• Basics of Stream I/O
• File I/O vs. Console I/O
• Class ifstream and ofstream
• Formatting output values
• Member functions in istream/ostream and
ifstream/ofstream
• Treating strings as I/O streams
(istringstream/ostringstream) (Optional)

2
Introduction
• What is File I/O?

• What is Stream I/O?


• Stream of bytes → Sequence of bytes
• Data are read from an input stream one character at a
time
• Data are sent to the output stream one character at a
time.

• Why do we need File I/O?

3
Abstraction of I/O (Console I/O)
Bytes or
Stream converted
of bytes cin high-level data
Keyboard (An istream object)
C++
Stream Bytes or high-
Program
of bytes cout level data
Console
(An ostream object)

• istream and ostream objects act as “middle


persons” between C++ programs and the I/O sources
(e.g., keyboard, console screen)

• These objects offer member functions and overloaded


operators for programmers to perform both low-level
(unformatted) and high-level (formatted) I/O 4
Low-Level and High-Level I/O
• Low-level I/O
• Unformatted
• Deals with individual byte
• Suitable for binary files
• E.g., JPEG Image, MP4 Video files, etc.

• High-level I/O
• Formatted
• Deals with built-in types and user-defined types
• Suitable for plain-text files (files containing only
printable ASCII characters)

5
Abstraction of I/O (File I/O)
Bytes or
Stream converted
Disk
of bytes An ifstream high-level data
input.txt
object
C++
Stream Bytes or high-
Program
of bytes An ofstream level data
output.txt
object

• To perform file I/O, we use ifstream and ofstream


objects

• ifstream and ofstream are subclasses of istream


and ostream respectively
• They offer everything istream/ostream offer plus some
file-specific member functions
6
Steps for Performing File I/O
1. Prepare a stream for reading/writing by creating
an ifstream/ofstream object
2. Read/write data via the stream object
3. When done with File I/O, close the stream
• Release all the resources in the memory associated with
the file
• Flush all data in the memory to the output file if
necessary

• Step 2 is the same as performing I/O using cin and


cout
7
File I/O vs Console (Keyboard) I/O
File I/O Console (Keyboard) I/O
Include both <iostream> Include only <iostream>
and <fstream>
ifstream/ofstream cin/cout are automatically
objects have to be explicitly made available
created. One object per file
File may not be opened Always available
successfully
Need to check when end-of- Usually don't have to check
file is reached (Input only) when end-of-input is reached
Need to close files when done No need to close
using them 8
Filenames and Directory
Structures
• Relative filename
• Relative to the directory (folder) where you run the program
• file1.txt Local Disk (C:)
• ..\Folder B\file2.txt Folder_A
(Windows
• Absolute filename systems) Folder_B
 file1.txt
• Full path (up to the root) + filename  file2.txt
• C:\Folder C\file1.txt Folder_C
• C:\Folder B\file2.txt  file1.txt
 program.exe

• Remember to represent \ as \\ in C++ source program


• E.g.: "C:\\Folder C\\file1.txt"
• On some OS (e.g., macOS, Linux), paths are separated
by (/) instead of (\) 9
Preparing a Stream for Reading
• Create objects of the class ifstream for file input
• E.g.:
ifstream fin("input.txt");

Call constructor
Stream type Name of object A c-string or
(variable) string object
(since C++11)
as argument

10
Preparing a Stream for Writing
• Create objects of the class ofstream for file
output
• E.g.:
ofstream fout("output.txt");

• If the file already exists, its original contents will be


erased!

• To retain the original file contents, use:


ofstream fout("output.txt", ios::app);

For “appending”
11
File Output: Example
1 #include <iostream> For using ofstream Content in the
2 #include <fstream> file output.txt
3 using namespace std;
4 Hello!
5 int main() { 0 1 2 3 4 5 6 7 8 9
6 /* Create an ofstream object for output.
7 A file named "output.txt" will be created */
8 ofstream fout("output.txt");
9 1. Create an
10 fout << "Hello!" << endl; ofstream object
11
12 for (int i = 0; i < 10; i++)
2. Write data
13 fout << i << ' ';
14 fout << endl; to stream
15
16 /* Close the stream to indicate that we are done
17 writing data to the file */
18 fout.close(); 3. Close stream
19 return 0;
20 } 12
File Open and Checking
1 #include <iostream>
2 #include <fstream>
3 #include <cstdlib> For using exit()
4 using namespace std;
5
6 int main() {
7 ofstream fout("output.txt");
8
9 // If we fail to open the file for output
10 if ( fout.fail() ) {
11 cout << "Cannot open the file" << endl;
12 exit( 1 ); // Terminate the program
13 }
14 The argument passed to exit()
15 fout << "Hello World\n"; is usually not used. Typically, we
16 fout.close(); use non-zero value to indicate
17 return 0;
18 }
unsuccessful termination

Check if a file is opened successfully before using it 13


File Open and Checking
1 ofstream fout;
2 string filename; We can delay opening a file by
3 using the member function
4 cout << "Enter a filename: "; open(), which expects a file
5 cin >> filename; name as a c-string
6
7 fout.open( filename.c_str() );
8
9 // If we fail to open the file for output
10 if ( fout.fail() ) {
11 cout << "Cannot open the file for output." << endl;
12 exit( 1 );
13 } c_str() is a member
14 function of the string class
15 // Write this to file
16 fout << "Hello World\n";
that returns an equivalent c-
17 string of a string object
18 fout.close(); 14
File Open and Close
1 ofstream fout;
2
3 fout.open("file1.txt"); Stream open and stream
4 … close work in pairs
5 fout.close();
6 …
7
8 fout.open("file2.txt");
9 …
10 fout.close();
11 …
12
13 fout.open("file3.txt");
14 …
15 fout.close(); An ifstream/ofstream object can be reused
to connect to different files, but it can connect
to at most ONE file only at any given time 15
File Reading (Input): Example
1 ifstream fin("data.txt");
2
3 // Terminate if the file cannot be opened for reading
4 if ( fin.fail() ) {
5 cout << "File could not be opened" << endl;
6 exit( 1 );
7 } Content in the
8
9 int x, sum = 0; file data.txt
10 1 27
11 // Assume there is no input error. 3
12 // Read until end of the file is reached
13 while ( !fin.eof() ) { 4
14 fin >> x; 5
15
16 // If successfully read an integer
17 if ( fin.good() )
18 sum += x;
19 }
20 cout << "Sum is " << sum << endl;
21 fin.close(); Sum is 40 16
• ↑ represents the “current file position”. An
ifstream object uses it to remember where (in a
file) to read the next input
1 2 7 \n 3 \n \n 4 \n 5 \n \n

• When a file is opened, the current file position is at
the beginning
• Every character fin reads would advance the
position by one

1 2 7 \n 3 \n \n 4 \n 5 \n \n

• The first time fin >> x is executed, fin reads 1
and stops reading when it encounters a character
that is not part of an integer. The current file
position stays at the unconsumed space character ˽ 17
1 2 7 \n 3 \n \n 4 \n 5 \n \n

• The next time fin >> x is executed, fin will
attempt to read an integer (a sequence of
characters that represents an integer)

1 2 7 \n 3 \n \n 4 \n 5 \n \n

• When fin encounters a character that is not part
of an integer, it stops
• This time, fin reads two bytes and then converts
“27” to integer value 27 and store the value in x

18
1 2 7 \n 3 \n \n 4 \n 5 \n \n

• After fin reads the last integer (the 5th time), the
current file position points at the ‘\n’ after ‘5’
• At this point, fin.eof() is still false

1 2 7 \n 3 \n \n 4 \n 5 \n \n

• When the next fin >> x is executed, fin skips all
whitespace characters until the end of file but it
fails to read any integer
• Thus, fin.good() is false and fin.eof()
becomes true
19
States of a Stream Object
• eof()
• Returns true if file reading has reached the end
• bad()
• Returns true if a reading or writing operation fails due
to some unrecoverable errors
• E.g.: disk full or file is deleted while an I/O operation is taking
place
• fail()
• Returns true if bad() is true or if the previous I/O
operation fails to read/write an expected character
• E.g.: A letter ‘Z’ is encountered when we are trying to read an
integer
• Usually recoverable
• good()
• Returns true if all of eof(), fail(), and bad()
return false 20
Simple Input Error Handling: Example
1 int x;
2 ifstream fin("data.txt");
3 // Suppose the file is opened successfully
4
5 // Read until end of file is reached
6 while ( !fin.eof() ) { Content in the
7 fin >> x; file data.txt
8
9 // If successfully read an integer 1 2A
10 if ( fin.good() ) 3
11 cout << x << endl;
12
13 if ( fin.fail() && !fin.eof() ) {
14 cout << "Failed to read an input value.\n";
15 break; // Stop reading immediately
16 }
17 } 1
18 … 2
19 fin.close(); Failed to read an input value. 21
(Optional)

Checking and Handling “Fail” or


“Bad” States
• For every input operation performed, you should
check if it is successful

• When a stream object state is “fail” or “bad”,


subsequent input operations will not take place
until the state is restored to “good”
• You can use member function clear() to restore the
stream state to “good”, or
• You can just print an error message and stop reading the
input

22
(Optional)

Error Recovery with clear():


Example 1 2 3↵
Valid #: 1
>> returns a non-zero Valid #: 2
1 int x = -1;
2 string tmp;
value if extraction is Valid #: 3
3 successful 123abc↵
4 while (x != 0) { Valid #: 123
5 // If successfully read an integer Invalid #: abc
6 if ( cin >> x ) a 123↵
7 cout << "Valid #: " << x << endl; Invalid #: a 123
8 123 a 456↵
9 if ( ! cin.good() ) { Valid #: 123
10 cin.clear(); Invalid #: a 456
11 // Clear the whole line 0↵
12 getline(cin, tmp); Valid #: 0
13 cout << "Invalid #: " << tmp << endl;
14 }
15 }
23
More about File I/O
• C++ imposes no structure on file
• i.e., no predefined format
• Byte is the basic unit
• To read data from a file, you need to know how the
data are formatted in the file
Program A for writing: Program B for reading:
1 ofstream fout("data.txt"); 1 ifstream fin("data.txt");
2 int i; double d; 2 int i; double d;
3 char c; string s; 3 char c; string s;
4 … 4 …
5 fout << i << endl; 5 fin >> i;
6 fout << d << endl; 6 fin >> d;
7 fout << c << endl; 7 fin >> c;
8 fout << s << endl; 8 fin >> s;
9 fout.close(); 9 fin.close(); 24
ifstream: a Subclass of istream
ofstream: a Subclass of ostream
• ifstream is a subclass of istream
• i.e., an ifstream object can be used as an istream
object

• ofstream is a subclass of ostream

• ifstream and ofstream offer everything


(member functions, etc.) istream/ostream offer
plus some file-specific member functions

25
Example
1 #include <iostream>
2 #include <fstream>
3 using namespace std;
ofstream is a subclass of ostream
4
5 void drawBox(ostream &out) { • Both cout (an ostream object)
6 out << "+-+\n"; and fout (an ofstream object)
7 out << "| |\n"; can be passed to the parameter of
8 out << "+-+\n"; drawBox(…)
9 } • That is, a subclass argument can be
10 passed to a superclass parameter
11 int main() {
12 ofstream fout("output.txt");
13
14 // Suppose the file is opened successfully
15 drawBox(cout); // Output a box on console screen
16 drawBox(fout); // Output a box to "output.txt"
17
18 fout.close();
19 return 0;
20 } 26
Example
1 #include <iostream> • An ifstream/ofstream object
2 #include <fstream> should always be passed as
3 using namespace std; reference parameters, so that I/O
4 can continue in the function
5 void drawBox(ostream &out) { through the same stream object
6 out << "+-+\n"; • If you pass by value, then there will
7 out << "| |\n"; be two stream objects handling the
8 out << "+-+\n"; same file. This is dangerous and can
9 } easily introduce errors
10
11 int main() {
12 ofstream fout("output.txt");
13
14 // Suppose the file is opened successfully
15 drawBox(cout); // Output a box on console screen
16 drawBox(fout); // Output a box to "output.txt"
17
18 fout.close();
19 return 0;
20 } 27
Function in <string> for String
Input
istream& getline( istream &is, string &s);
• Reads characters from is into s until:
• The newline character '\n' is encountered, or
• EOF is encountered
• The delimiter '\n' is removed from the stream but not
included in s
1 // A string object for storing a line of file contents
2 string buf;
3 ifstream fin( "temp.txt" );
4
5 while ( getline( fin, buf ) ) {
6 cout << buf << endl; Example: display the contents
7 } of file “temp.txt”, line by line,
8 fin.close(); using string object 28
(Optional)

Other Member Functions in


istream Object for Input
istream& getline( char* buf, size_t n );
• Reads characters into buf until:
• n - 1 characters have been read, or
• The '\n' delimiter is encountered , or
• EOF is encountered
• Note:
• buf is an array of characters (c-string)
• Delimiter '\n' is consumed but not included in buf
• NULL character '\0' is automatically appended to buf

• The getline() in this page is a member function of istream


class for c-strings
• The getline() in the last page is a function for string objects 29
Low Level I/O
• Sometimes, you may want to perform I/O at a
character level
• Read/writes are performed byte by byte
• E.g., encryption/decryption of a file

• The ostream and istream classes provide several


member functions for such purpose
• ostream::put() for output
• istream::get() for input

30
Member Functions in ostream
for Low-level Output
ostream& put( char ch );
• Writes the character ch to the output stream
• E.g.:
1 // Print A to screen
2 cout.put('A');
3 // Print B and C and \n to screen
4 cout.put('B').put('C').put('\n');
5
6 ofstream fout("output.txt"); // Assume success
7 // Write D to file "output.txt"
8 fout.put('D');
9 // Write E and F and \n to file "output.txt"
10 fout.put('E').put('F').put('\n');
11
12 fout.close(); 31
Member Functions in istream
for Low-level Input
int get();
• Reads a character and returns its ASCII value
• Returns –1 if good() is false
1 int c;
2 ifstream fin( "input.txt" );
3
4 c = fin.get();
5 while (c != -1) {
6 cout.put( (char)c );
7 c = fin.get();
8 }
9 fin.close();
Example: Prints the contents of file “output.txt”, character by character
32
get() vs >>
• get()
• A member function that reads only characters. Won’t
skip whitespaces. Every character counts
• >>
• An operator that reads values of several data types.
Whitespaces may be skipped
• Compare these two code fragments:
1 char ch; 1 ifstream fin("input.txt");
2 ifstream fin("input.txt"); 2 int ch = fin.get();
3 while ( fin >> ch ) 3 while (ch != -1) {
4 cout.put( ch ); 4 cout.put( (char)ch );
5 fin.close(); 5 ch = fin.get();
6 }
7 fin.close(); 33
1 #include <iostream>
2 #include <fstream>
3 #include <string>
4 using namespace std;
5
6 int main() {
7 string input, output;
8 int ch;
9
10 cout << "Enter input file name: ";
11 cin >> input;
12 cout << "Enter output file name: ";
13 cin >> output;
14 ifstream fin( input.c_str() );
15 ofstream fout( output.c_str() );
16
17 while ( (ch = fin.get()) != -1 )
18 fout.put( ch );
19
20 fin.close();
21 fout.close();
22 return 0;
23 }
Example: File Copy (Duplicate)
34
Summary
• 3 steps for performing file I/O:
• Create an ifstream/ofstream object and open a file
• Perform I/O through the stream object
• Close the stream object when done

• How to check if files are opened successfully

• How to check the stream states after every input


operation
Reference:
istream: https://cplusplus.com/reference/istream/istream/
ostream: https://cplusplus.com/reference/ostream/ostream/
ifstream: https://cplusplus.com/reference/fstream/ifstream/
ofstream: https://cplusplus.com/reference/fstream/ofstream/ 35
(Optional)

ostringstream and
istringstream
• The <sstream> library provides these two classes
for manipulating strings as if they are i/o streams

• ostringstream
• Format your data to a string object as output
• Subclass of ostream
string ostringstream
object object
• istringstream
C++
• Read formatted data from a string object as input Program
source
string istringstream
• Subclass of istream object object

36
(Optional)
ostringstream: Example
1 #include <iostream>
2 #include <string>
3 #include <sstream> For using ostringstream
4 using namespace std; and istringstream
5
6 int main() {
7 ostringstream sout;
8 int x = -12;
9 double y = 345.67;
10
11 sout << x << " " << y << endl;
12 sout << "ABC" << endl;
13
14 string s = sout.str();
15
16 cout << "Length = " << s.length() << endl;
17 cout << s; Length = 15
18 return 0; -12 345.67
19 } ABC 37
(Optional)

istringstream: Example
1 #include <iostream>
2 #include <string>
3 #include <sstream>
4 using namespace std;
5
6 int main() {
7 string input_str(" 123 456 78 9012 ");
8 istringstream sin(input_str);
9 int x;
10 while ( !sin.eof() ) {
11 sin >> x;
12 if (sin.good())
13 cout << x * 2 << endl; 246
14 } 912
15 return 0; 156
16 } 18024 38

You might also like