Designing Classes and Programs

Download Report

Transcript Designing Classes and Programs

Announcements

Midterm 2 is on 26th of December, Friday, 17:40 –
19:30
 Places will be announced later

Homework 5 is postponed to December
4, 13:00.


Algorithmically not so difficult
but you may encounter some complications if you
do not know what to do.
CS201 – Introduction to Computing – Sabancı University
1
Stream Processing and stream
operations for I/O (Input / Output)

We’ll see
 section 6.3 and 6.4 (some parts excluded)
• Different methods of word and numeric input
processing
• For example, counting words of
– an input stream (most famous example is cin)
– a text file
 different characteristics of cin (mostly not in the book)
 section 9.1, 9.2 (and maybe 9.3 in recitations)
• input and output operations on streams
– reading a full line into a string
– reading character by character
 Some stuff is not in the book.
CS201 – Introduction to Computing – Sabancı University
2
What’s an I/O (Input/Output) Stream?



A sequence of characters flowing between the I/O devices
and programs
 therefore it is a buffer area for I/O
We extract and insert using >> and << operators,
respectively
cin is the standard input stream (i.e. keyboard)
Ali Veli 45 Ahmet cs201

cout is the standard output stream (i.e. monitor)
John George 3 Mike Joe

>>
<<
We also have file streams (for file I/O) that we will see later
CS201 – Introduction to Computing – Sabancı University
3
Counting Words of Keyboard Input

Problem: where to stop processing, if number of inputs is not
known – 2 solutions
 until a sentinel value
• applicable to number processing as well (have seen before)

until the end of input stream
• end-of-file indicator (Ctrl-Z in Windows) - we will see

Sentinel based solution - See sentinel.cpp
 Input and count words until the sentinel value (in this example,
"end") is entered.
 Input may be entered in different lines
 the sentinel value ("end") should not happen in the text of
which you want to count words
• otherwise you do not count the rest

can be applied to counting numbers as well
• without any change
• just enter numbers instead of words
• But it does not check whether the entered value is a valid number
or not
CS201 – Introduction to Computing – Sabancı University
4
Counting Words of Keyboard Input

Non-sentinel version - See countw.cpp
read one word
and check if
string word;
successfully
int numWords = 0;
read
while (cin >> word)
{
numWords++;
}
cout << "number of words read = "<<numWords << endl;



Process until the end of the stream
Input may be entered in different lines
end of stream is specified by end-of-file character, Ctrl-Z
• Type Ctrl-Z (press Ctrl first and while it is pressed, type Z) as the
first character on a new line when the program runs and waits for
more words. That signals the end of input.
• you may need to press the “enter” key twice in Windows®

Similar solutions can be applied to integer/real processing as well
 we will give examples later
CS201 – Introduction to Computing – Sabancı University
5
Detailed Examination of cin


The statement cin >> variable
 reads the value of variable, and
 returns the remaining stream for other data input
cin >> num1 >> str >> mydouble actually works
as
(((cin >> num1) >> str) >> mydouble)
Although it may seem strange, cin >> variable also
returns a boolean value depending on the success of the
input operation
 true, if input operation is successful
• if there was data and data was of the correct type
• type is not a problem for strings since every input is string
• but for numeric data, type is a potential problem

false, if there is no data (end of file is reached) or data is
of wrong type
CS201 – Introduction to Computing – Sabancı University
6
sum10nums.cpp revisited (not in book)

Can we check whether the input is a valid integer before adding up?
 Yes, see sum10validnums.cpp (not in book)
int num, sum, count;
sum = 0;
//initialize sum
cout << "Please enter 10 integers to add up: ";
for (count=1; count <= 10; count++)
read the next
{
number and checks
if it is a valid integer
if (cin >> num)
{
cout << num << " is a valid entry" << endl;
sum += num; // add it to the sum if valid
}
else
//else display a message
{
cout << "entry #" <<count<<"is invalid"<< endl;
}
}
cout << "the sum is: " << sum << endl;
CS201 – Introduction to Computing – Sabancı University
7
sum10nums.cpp revisited (not in book)


This solution works for valid numbers
 but does not work for invalid numbers as intended
• actually does not read inputs after the first invalid entry
• reason is that once an invalid input is detected, some error
flags are set automatically, and while they are set, cin does
not work
• in the program you may clear the error flags by cin.clear()
• however you have to skip the invalid entry since the invalid
entry is still in the stream, but how?
– There is no particular stream member function to skip the next
data on the stream. You can skip data on stream by just
reading it.
– Trying to read into an integer variable does not help either.
– possible solution is to read it into a string variable. Every word
can be read into strings.
See sum10validnumsfixed.cpp (not in book) for the fixed program
 next slide
CS201 – Introduction to Computing – Sabancı University
8
sum10nums.cpp revisited (not in book)
int num, sum, count; string s;
sum = 0;
//initialize sum
cout << "Please enter 10 integers to add up: ";
for (count=1; count <= 10; count++)
read the next
{
number and checks
if it is a valid integer
if (cin >> num)
{
cout << num << " is a valid entry" << endl;
sum += num; // add it to the sum if valid
}
if input is not valid, clear
else
the error flags
{
cin.clear();
and skip the invalid entry
cin >> s;
cout << "entry #" <<count<<"is invalid"<< endl;
}
}
CS201 – Introduction to Computing – Sabancı University
9
Finding Min/Max of input numbers

Iterative search of all candidates
 if the current candidate is smaller/larger the the min/max so
far, then set the candidate as current min/max
 what is going to be the initial value of current min (or max)?
• for min: initialize to the possible maximum value
• for max: initialize to the possible minimum value
• Reason is to make the first input current min (max)


Largest int and double values are found in <climits> and
<cfloat>, respectively (or <limits.h> and <float.h>)
 you’ll need to #include them
 INT_MAX and INT_MIN are max and min int values
 DBL_MAX and DBL_MIN are max and min double values
What happens if all input numbers are INT_MAX (INT_MIN)?
 no problem
CS201 – Introduction to Computing – Sabancı University
10
Example

Find min of input values until end-of-file or until an invalid
input is entered
 see mindatainput.cpp (not in the book as is)

Study yourselves
 Modify the program to discard invalid integers
 Find max
 repeat for double values
CS201 – Introduction to Computing – Sabancı University
11
Streams for reading and writing files

We’ve seen the standard input stream cin, and the standard
output stream cout




For reading from the keyboard, writing to the screen
Accessible from <iostream>
Other streams let us read from files and write to files
Why do we need such a file I/O?
 Because files are permanently stored; whereas the
keyboard entry is for one time and screen output is volatile
 We can input the same data several times if we use file
input
• Or we can modify the input file and re-run program using the
modified data

We can save the output for future reference
CS201 – Introduction to Computing – Sabancı University
12
Streams for reading and writing files


syntax for reading and writing is similar to cin and cout,
because they are all streams
To use a file stream, it must be opened first
 Opening binds the stream variable to a physical file
• After opening, I/O to/from this file can be performed.

Should close file streams, but happens automatically for
input streams when the program finishes.
• We need to close output streams as will be discussed later
cin and cout are not opened and closed, because they
are standard streams and compiler knows how to
handle them
Input files are generally text files that can easily be
generated using Notepad.


CS201 – Introduction to Computing – Sabancı University
13
Input file stream: Note similarity to cin
string word;
int numWords = 0;
// # words read so far
while (cin >> word)
// while read succeeded read and
{
numWords++;
// count
}
cout << "number of words read = " << numWords << endl;
string word;
int numWords = 0;
ifstream input;
string filename;
//defining input file stream
cin >> filename;
input.open(filename.c_str());
// input the file name
//open the file
while (input >> word) //while read succeeded from file
{
numWords++;
}
cout << "number of words read = " << numWords << endl;
CS201 – Introduction to Computing – Sabancı University
14
Counting words in a file




See countw2.cpp
Idea is in the previous slide
Enhancement: also finds the average word length
 add the word lengths up and at the end divide it by the
word count
Study for yourselves
 find the largest and smallest word in a file
CS201 – Introduction to Computing – Sabancı University
15
Example (not in book)

Find the longest word (max number of characters) in a file.
 Idea for algorithm/program
• Read every word, remember the longest word read so far
• Each time a word is read, compare to longest-so-far. If
longer, then there’s a new longest-so-far

See longestword.cpp (not in book)
 why did we initialize maxlength to 0?
• zero is the minimum possible word length
• initialization to any negative value would also work

what happens if there are more than one words with the
same max length in the file?
• finds the first one (finding all either requires processing
the same file twice or requires some other tools that we
will learn in a few weeks)
CS201 – Introduction to Computing – Sabancı University
16
More on file/stream Input


All input file stream operations are defined for ifstream class
 need to #include <fstream>
• a standard class, no cpp necessary
 ifstream::open(name of the file)
• file name must be a C-style string
• string member function c_str returns the C-style equivalent
• that is why we had input.open(filename.c_str())
 as in cin, operator >> used to extract any type of value from file
(input stream)
What happens if there is no such file?
 open fails and nothing can be read
 use ifstream::fail() member function to check if the file is
opened successfully
if (input.fail())
{
cout << "cannot open " << filename << endl;
return 0;
//stop program
}
CS201 – Introduction to Computing – Sabancı University
17
More on file/stream Input

How to check the end of the file?
 as in cin
>> operator returns true if read is successful; returns
false if the end of file is reached or there is an input
type error

end_of_file member function ifstream::eof() can
be used specifically for end of file controls
• returns true if the end of the file is reached and there
are no more data to read
– Here the file to be checked is the input file stream
on which the eof member function is working
• returns false if there are still data to read
CS201 – Introduction to Computing – Sabancı University
18
More on file/stream Input

Type problems
 not a problem for string input, since every word is a
string
 may cause a problem for numeric input
>> operator returns false if the input is not a proper numeric
data while reading numeric input

as in cin
• clear the error flags using clear member function
ifstream::clear()
• then skip the non numeric data by reading it into a dummy
string variable, and continue processing

Now we will give a file processing example to illustrate the
use eof function and input type problems
CS201 – Introduction to Computing – Sabancı University
19
Example (not in book)


Count the total number of integers in a file that may also
contain non-integer values
 If you encounter a non-integer data in the file, skip it and
continue until the end of the file
We have to check the end of file using eof function
 because extraction ( >> operator) returns false both
when end-of-file is reached and when the input is not an
integer
• we have to differentiate between these two cases
• loop control is until the eof
• inside loop, check if the input is successful and count
accordingly

let’s see countintegers.cpp (not in the book)
CS201 – Introduction to Computing – Sabancı University
20
More on file/stream input


There is an abstract pointer that shows the next input to
read
 when a file is opened, this pointer shows the first
character
 when read, it moves towards the end of file sequentially
it is possible to move that pointer using
ifstream::seekg(n) member function where n is the
position to be moved.
 seekg(0) moves to the beginning of the file – necessary
to process the same file more than once
 For this course it is sufficient to use seekg(0) when
necessary, but later you may need to use seekg with
nonzero arguments for more sophisticated file
processing applications
CS201 – Introduction to Computing – Sabancı University
21
Example (not in book)

Example: calculate average word length of a file and find
the total number of words that have more than average
word length characters
 we need two pass over the same file
• one for average, one for number of words longer than the
average


see longerwords.cpp (not in the book)
Two important tips
 use clear before calling seekg

always pass a file stream to a function as a reference
parameter
CS201 – Introduction to Computing – Sabancı University
22
ofstream: Output file stream


We can also use files for output
ofstream class
 use is similar to cout
 first open the file (as in ifstream)
 then use << operator to write into output file stream
 better if you close the file using close() member function (to
be on the safe side, close all output files when done)
 #include <fstream> is needed (as in ifstream)

When opened, the previous content of the file is
automatically deleted.

To append to the end of an output file without deleting the
previous content, use ios::app as the second argument of open
Example (not in book)
 write a program to create a file and fill that file with 10 random
numbers (between 1 and 100). One number per line
 see outfile.cpp

CS201 – Introduction to Computing – Sabancı University
23
More on streams and character/string
processing


There are several other classes, functions and facilities about
streams and string/character processing
 I/O is an ocean, need several weeks to cover all
 I have explained some basics only
 you are responsible what I have covered and will cover, plus the
reading assignments
 but in future, if you need something that we did not cover, refer to
the book and MSDN library to see if there are ways of doing it
What we did not cover from Chapter 6?
 WordStreamIterator class
• introduced in 6.3.7 and used later
• a different way of using ifstream class
• if you are interested, read and use it, but not responsible

CTimer class
• useful to take timings (section 6.4.4) – may need later


Finding mostly occurred word in a file (may be covered in
recitations)
StringSet class (section 6.5), not responsible.
CS201 – Introduction to Computing – Sabancı University
24
String Utility Functions - Revisited

Free functions defined in strutils.h (Tapestry Utilities)
 should include strutils.h at the beginning of the program
 should add strutils.cpp to the project
 some functions are the following (refer to above files for
the full list)
ToLower
ToUpper
StripPunc
tostring
atoi
itoa

return a lowercase version of a string
return an uppercase version of a string
remove leading/trailing punctuation
int-to-string conversion (e.g. return "123" for 123)
string-to-int conversion (e.g. returns 123 for "123")
same as tostring
Used some of them before and may need later
CS201 – Introduction to Computing – Sabancı University
25
Chapter 9 - Strings, Streams and
Operators

Read 9.1 – YOU ARE RESPONSIBLE
 character processing using type char
I will cover this part later
9.3 has a good case study, read it.
 But I will not go over it
9.4 – not responsible
we will partially cover 9.2
 we will cover 9.2.1 and 9.2.4
 9.2.2 and 9.2.3 are extremely important for sophisticated
I/O




• 9.2.2 will be covered
• Read 9.2.3.
CS201 – Introduction to Computing – Sabancı University
26
9.2.1 – input using getline

getline is a free function to read a full line from input
stream
 input stream can be a file or cin
>> operator reads one by one
• blanks are delimiter


getline reads whole line and stores in its string
parameter
Syntax
 getline(input stream, string variable)
getline also returns a boolean value
 true if input successful
 false if unsuccessful
 used in loops to process until the end of file
CS201 – Introduction to Computing – Sabancı University
27
Example (See filelines.cpp)

Count number of lines and number of characters of a file
ifstream input;
string s;
int numLines = 0;
int numChars = 0;
string filename = PromptString("enter name of input file: ");
input.open(filename.c_str());
if (input.fail() )
{
cout << "could not open file " << filename << endl;
return 0;
}
read one line and check
if input is successfully
read (i.e. not at the end
of file
while (getline(input,s))
{
numLines++;
numChars += s.length();
}
cout << "number of lines = " << numLines
<< ", number of characters = " << numChars << endl;
CS201 – Introduction to Computing – Sabancı University
28
Using getline on cin

You can read a line of data from keyboard
string s;
getline(cin,s);

discard the rest of a line after reading the input
int num;
cin >> num;
getline(cin,s);

//gets the whole line into s
// input
// discard the rest of the line
//by reading in a dummy string
You will need an extra empty line in the input (i.e. press the
“enter” key twice) in Windows®
 Only when you use getline for cin, not for getline for files
CS201 – Introduction to Computing – Sabancı University
29
Input using get


get is a member function for ifstream
reads one character into its char argument

does not skip blanks and control characters
• read them as characters



get also returns a boolean value
 true if input successful
 false if unsuccessful
 used in loops to process until the end of file
Example: similar example as before
 counts lines and characters of a file
 but also counts blanks (not in the book)
See filelines2.cpp and next slide for the code
CS201 – Introduction to Computing – Sabancı University
30
int numChars = 0;
int numLines = 0;
int numBlanks = 0;
char ch;
//be careful about the type char
string filename = PromptString("enter name of input file: ");
ifstream input;
input.open(filename.c_str());
if (input.fail() )
{
cout << "could not open file " << filename << endl;
return 0;
while next character is read
}
successfully (i.e. end of file is not
reached)
while (input.get(ch))
{
numChars++;
if ('\n' == ch)
if character is a newline character,
{
numLines++;
increment line counter
increment }
character else if (' ' == ch)
counter
{
numBlanks++;
if character is a blank, increment
}
blank counter
}
cout << "number of lines = " << numLines << endl
<< "number of characters = " << numChars << endl
<< "number of blanks = " << numBlanks <<endl;
CS201 – Introduction to Computing – Sabancı University
31
9.2.2 Input String Stream

In files, data are generally line oriented (easier to understand
for human beings)
 Example (student name, lastname and grades, one line
per student)
John Ozcalisir 100 100 100 100
Bill Yatar 12 40
Alice Idareeder 50 55 46

Problem: We have to process the data line by line, but we
do not know how many grades do we have in one line
• Reading using >> does not help since we miss end of line

Solution: Read data line by line (using getline) into a
string variable and then parse each line
• We need a tool that allows us to use >> on strings in order
to extract data out of each line
• This tool is called input string stream
CS201 – Introduction to Computing – Sabancı University
32
Input String Stream – parselines.cpp
...
while (getline(ifile,s))
{
total = 0; count = 0;
istringstream input(s);
input >> name >> lastname;
Read one line at each iteration
Create an input string stream
out of the current line
Read two strings from
while (input >> num)
current line
{
count++;
total += num;
Read numbers until the end of
}
line
if (count != 0)
{
cout <<name<<" "<<lastname<<": average of "<<count<<"
grades = " << double(total)/count << endl;
}
else
{
cout << "wrong or no input!" << endl;
}
}
CS201 – Introduction to Computing – Sabancı University
33
Input String Stream – Details and Tips

istringstream is a class defined in sstream header file
 You have to #include <sstream>
No cpp necessary (standard class)
istringstream object must be created by passing the source
string as an argument
 See previous example
 You cannot later change the source string


• That is why we have created a new istringstream object for
each line (THIS IS VERY IMPORTANT).

>> returns a boolean value depending on the success of input
operation (as in other streams)

We also have output string stream
 Read Section 9.2.3
CS201 – Introduction to Computing – Sabancı University
34