Showing posts with label Stream. Show all posts
Showing posts with label Stream. Show all posts

Saturday, September 5, 2009

Streams as parameters

The most important thing to remember when passing a stream to a function as a parameter: the formal parameter needs to be a reference parameter

It makes sense to require that since the function operates with the stream. The state of the stream changes and the change must be passed back to the actual parameter. As a rule the actual parameter needs to be of the same type as the formal parameter of the function, except when:

the type of the formal
parameter is
the actual parameter
can also be
sitram&ifstream or istringstream
ostream&ofstream or ostringstream


In practice that makes writing more general functions possible: the same function can operate with different types of streams.

A small example function:

int readNumber( istrea& stream )
{
    int number;
    stream >> number;
    if( !stream )
    {
        return ERROR;
    }
    else
    {
        return number;
    }
}

Now the same function can be used for reading input from the keyboard:

int number;
number = readNumber( cin );

of from a file:

ifstrea database( "input.txt" );
int number;
number = readNumber( database );

or from a string:

istrinigstream numberstring("12345 67890 101112");
int number;
number = readNumber( numberstring );

Reference: daniweb, bytes, cplusplus

Previous post

Next post


Problems with streams

The following problem situations can occur when using streams:
  • An attempt to write data into a outputstream fails (e.g. the disk is full)
  • An attempt to read data from an inputstream even though everything has already been read (e.g. the read operation is at the end of file)
  • Data of the wrong type is attempted to read from an inputstream (e.g. an integer is expected but the user types characters)
Noticing the problematic situations is easy with the following details:
  • All previously introduced stream operations evaluate the stream the operations is directed to ( peek() and get() without parameters are exceptions)
  • A stream used as a condition evaluates true only if the operation was successful (initialization included)
The following useful examples can be done based on these:

Connecting an inputstream to a file and reading it a line at a time:

ifstream file( "products.dat" );
if( !file )
{
    cerr << "open failed!" << endl;
    return ERROR; // depends on the situation
}
string line;
while( getline( file, line ) )
{
    ...
    // here work with the read data
    ...
}

noticing input of the incorrect type:

cout << "give number: ";
int number;
while( !(cin >> number) )
{
    cerr << "Invalid input, try again!" << endl;
    cin.clear();
    cin.ignore( 1000, '\n' );
}

The cin's own function clear() has been used to deal with the error situation above. The stream malfunctions every time an error occurs when handling data with it. Not even legal operations work any longer. Sometimes the situation can be fixed with the clear() function. Execution can (sometimes) go on normally afterward. Some errors cannot be fixed with clear() (e.g. the end of file has been met)

How to see the difference between the end of stream error and some other error situation:

while( getline( stream, line ) )
{
    ...
}
if( !stream.eof() )
{
    // Read failed for some other reason than
    // the end of the stream
}

The stream's own function eof() returns true only if an attempt has been made to read from the stream after it has already ended. Also peeking the next character in the stream with the peek() function is sometimes an useful way to deduct whether the input has been read entirely or not.

Last, an example on how to read the following input stream:

tel.number1 name1
tel.number2 name2
...

with the code:

int number;
string name;

while( stream >> number && getline( stream, name ) )
{
    // do stuff with the name and number
}
if( !stream.eof() )
{
    // invalid line in input
}

Reference: daniweb, dreamincode, cplusplus

Previous post

Next post


Wednesday, September 2, 2009

Operations with inputstreams

cin >> variable

Reads the next word from the stream, interprets it as the same type as the variable and saves the value into the variable. The variable can be of any basic type or string.


cin.get()

Reads and returns the next character in the stream. At the end of input EOF is returned.


cin.get( chr )

Reads the next character into the parameter that must be of the type char.


getline( cin, str )

Reads a line of input from the stream and saves it into a parameter of the type string.


getline( cin, str, chr )

Like above but reads only until meets the first character matching chr.


cin.ignore( how_many, chr )

Reads at most how_many characters from the stream or until meets the first chr. The read characters are "thrown away". How_many is of the type int and chr char.


cin.peek()

Returns the next character in the stream. The character is not read from the stream but the next read operations return it also Returns EOF at the end of input.

Reference: cplusplus, augustcouncil, elcel

Previous post

Next post


Tuesday, September 1, 2009

Streams in C++

In C++ streams are represented with datatypes implemented in a number of libraries:

#inlcude <iostream>
istream
Inputstreams usually already associated with the keyboard (cin).
ostream
Outputstreams usually already associated with the monitor (cout or cerr)


#inlcude <fstream>
ifstream
Inputstreams the user must associated with a file on the computer disk
ofstream
Outputstreams the user must associated with a file on the computer disk


#inlcude <sstream>
istringstream
inputstreams the user can use to read from a string using the formatting facilities provided by streams
ostringstream
Outputstreams the user can use to write to a string using the formatting facilities provided by streams

A programmer does not need to worry about associating cout, cin and cerr. They can always be used straight after #include<iostream>. Using streams usually consist of three phases (cin, cerr and cout exceptions):
  • Initializing (connecting, associating)
  • Operating with the stream (read, write etc...)
  • Closing
Before handling data with the streams found in fstream and sstream libraries they must be initialized:

ifstream: A variable of the type ifstream is declared and the name of the file to be read is given:

ifstream stream_name( file_name );

ofstream: A variable of the type ofstream is declared and the name of the file to be written into is given:

ofstream stream_name( file_name );

istringstream: A variable of the type istringstream is declared and the string from which the input is read is given:

istringstream stream_name( s_name );

ostringstream: A varible of the type ostringstream is declared.

ostringstream stream_name;

The file_name is not of the type string. It is of an older character string type adopted from the C language. The programmer must give the name of the correct type:

string file_name;
cin >> file_name;
ifstream file( file_name.c_str() );

the c_str() function returns a character string of the c-style string type matching the original string-typed string. The file_name can also be a character string literal:

ifstream file( "inputs.txt" );

After being initialized, different operations can be done with the stream depending on its type and whether it is an input or an output stream (phase 2).

Working with streams can be confusing because of different alternative ways to do things:

operations: cout << "Hello!";
functions: getline( cin, cstring );
own function: cout.put( 'a' );

Operations that can be used with all kinds of outputstreams (e.g. cout):

cout << value << endl;

Prints the value into the stream: the value can be of any basic datatype or string.

cout.put( c );

Prints one character c(char) into the stream

There are no more essential printing operations. Almost everything can be done with << operator.

The stream must be closed when it is not needed any longer (phase 3). If it isn't properly closed it will needlessly keep on using the system's resources. There are two ways to close a stream:
  • If the stream is a local variable, C++ automatically closes it when the code block the stream was defined in is exited.
  • The stream can also be "manually" closed if needed with the stream's own function close():
ifstream database( "phonenumbers.dat" ); // using the stream
...
database.close();

The stream cannot be used after closing unless it is initialized again.

cin, cout and cerr

cin is used for reading from the keyboard and cout for printing on the screen. cerr has the same functionality as cout but it is meant for printing the error messages of the program. All other output is printed into cout.

Reference: cplusplus, exforsys, msdn

Previous post

Next post


Streams

Most programs have some kind of I/O operations:
  • Reading data from a file on the computer's disk into the program
  • Saving the results of the program into a file on the disk for future use
There must be a way in a programming language to represent the real world disk files in such a way that a program can understand them. Usually a special data type that offers operations for reading and writing data is used. In C++ a data type called a stream is used for this purpose. In fact, besides file I/O, all input and output operations in C++ are done with streams.

The stream can be thought of as a line of characters following in a specific order in one direction without ever changing their order.
  • Only the first character of the stream can be read from the stream ( with the operation get() )
  • Writing can only be done after the last character in the stream( with the operation put() )
All other stream operations can be implemented with get and put. Not changing the order of characters in a stream is essential:
  • If the user types "abcdef" on a keyboard undoubtedly the program gets the same characters in the same order from the input stream(cin)
  • If the program writes characters into a stream connected to a file it is desirable that the characters are saved in the same order they were written into the stream
Streams are sequential in nature: data can only be managed in the same order it is in the stream. A stream is simply a sequence of bytes, that means, if a program is interested in the fifth character in the user's input, the preceding four characters must be read first. The same applies to a stream connected to a file: the file must be read from beginning to end. In reality, disk files can be read and written in an arbitrary order.

A stream is usually connected to a file, the screen or the keyboard. However, streams can also be used to connect two programs to each other. The interesting thing is that streams can always be handled in the same way, regardless of what they happen to be connected to.

Reference: cplusplus, msdn, exforsys


Previous post

Next post