Programming: Stream classes in C++ (very very basic)

Post here about scripting and programming for HaloPC (audio, network, ai, etc.)
Post Reply
kyboren





Posts: 58
Joined: Thu Feb 12, 2004 8:49 pm

Programming: Stream classes in C++ (very very basic)

Post by kyboren »

Well, what the heck, I have nothing better to do, so I'll write a quick post on how to use streams (particularly file streams) in C++.


First off, all streams are derived from basic_streambuf, the lowest-level class for I/O. Everything gets derived quite a few times, so you'll most likely won't ever see that. Anyway, I'd like to start out by saying that one of the main advantages to using streams is that since all streams derive from istream and/or ostream, you can read and write any stream, no matter whether it affects the console display, a file, a network connection, etc. This means that you can have a function take a stream input and will work the same for both keyboard input and file input, with no modification to the code :)

Anyway, let's get crackin'. The three file stream types are:
  • std::fstream
  • std::ifstream
  • std::ofstream
std::fstream - A generic stream object for files. This will accept both input and output :)
std::ifstream - Same as above, but only allows input (so you can only read the file)
std::ofstream - Same as first, but only allows output (only writing)

Before we really begin, let's learn some basic formatting. These member functions (the C++ name for these is 'string manipulators') are from ios (or ios_base, I forget), so any stream class will support these.
  • left - Left-justifies text
  • right - Right-justifies text
  • width(streamsize s) - Sets the width of the fielf (for right-justification) ***
  • fill(char c) - The character to fill blank spaces with ***
  • oct - Use the octal (radix of 8) number system to display numbers
  • dec - Use the decimal (base-10) number system (default)
  • hex - Use the hexadecimal (radix 16) number system
  • flush - Flushes the buffer (actually writes the data)
  • endl - Adds a newline to the stream and flushes it
Importat note: To use the manipulators that take parameters, you must include <iomanip>

You can use those in two main ways (there is another but I don't want to go over it):
-Call them as member functions
-Call them in a stream expression

Here's an example using the good ol' iostream class cout (all classes from the ios family work):

Code: Select all

//Method 1
#include <iostream>

int main()
{
     std::cout.width(15);
     std::cout.fill('.');

     std::cout << 256;
}

//output: 
//............256
Is the same as:

Code: Select all

//Method 2
#include <iostream>
#include <iomanip>

int main()
{
     std::cout << std::setw(15) << std::setfill('.') << 256;
}
//output: same as above
So, either call width() or fill() explicitly, or include iomanip, call setw() and setfill() [respectively], and use them as manipulators in an expression.

Now here's an example showing use of everything I just said:

Code: Select all

#include <iostream>
#include <iomanip>

int main()
{
    std::cout << std::setw(50) << std::setfill('#');
    
    std::cout << std::right << "Hello!" << std::endl;
    std::cout << std::left << std::oct << 40 << " (oct), " << std::dec << 40 << " (dec), " << std::hex << 40 << " (hex)." << std::endl;
}
//output: 
//############################################Hello!
//50 (oct), 40 (dec), 28 (hex).
[/quote]

Now, I'll show you how to make your very own manipulators!

Say you do a lot of:

Code: Select all

std::clog << "\t***ERROR***" << std::endl;
Well, we can make a manipulator to do this in one fell swoop:

Code: Select all

std::ostream &err(std::ostream &s)
{
    s << "\t***ERROR***";
    return s;
}
It's a pretty simple concept, really. Yes, there is a reason we are returning a reference to the stream object. If you reallllly want to know why just post and I'll tell you (but I don't feel like explaining it right now :) ).


Here's the code:

Code: Select all

#include <iostream>
#include <iomanip>

std::ostream &err(std::ostream &s)
{
    s << "\t***ERROR***";
    return s;
}

int main()
{

    std::cout << "Hi... " << err << std::endl;
    
    std::cin.get();
    
}
//output:
//Hi...     ***ERROR***
Now let's take a look at some basic functions:
  • read(char *d, streamsize s) - Reads s characters and places them in d.
  • write(const char *d, streamsize s) - Writes s characters of d
  • get() - Gets a single character (return value is the character)
  • unget() - Puts the character back in the buffer that you just read
  • peek() - Peeks ahead one character in the buffer (doesn't move the pointer to the current location)
  • put() - Puts a character (duh)
  • seekg(streamoff o, ios_base::seekdir d) - Seeks the input pointer to offset o from ios::beg, ios::cur, or ios::end (the beginning, current position, or end of a stream)
  • seekp(streamoff o, ios_base::seekdir d) - Same as above, but for the output
  • tellg() - Gives current location in input stream
  • tellp() - Same, for output
  • clear() - Clears state of stream object (i.e. clears any errors like eof() below)
  • eof() - Returns a bool. "Has the End-of-File been reached?"
  • good() - Returns a bool. "Is this stream good?"
  • fail() - Returns a bool. "Has this stream failed?"
  • bad() - Returns a bool. "Is this stream bad?"
  • getline(char *s, streamsize n, char d) - Reads a line. s is the string to put the data in. n is the size of the string s. d is an optional parameter (well actually getline is overloaded but w/e) specifying the 'line-break' character (you could say it's '
kaptainkommie




Wordewatician 500

Posts: 732
Joined: Wed Nov 26, 2003 11:59 pm
Location: Raleigh, NC, USA

Post by kaptainkommie »

Stickied.
ShadowSpartan





Posts: 151
Joined: Mon Jun 13, 2005 12:45 pm

Post by ShadowSpartan »

I think you forgot to sticky it. Lol. BTW nice tutorial.

-ShadowSpartan
kyboren





Posts: 58
Joined: Thu Feb 12, 2004 8:49 pm

Post by kyboren »

Thanks. I've got nothing better to do today, either, so I might just write another one.
live2board





Posts: 17
Joined: Sun Mar 27, 2005 10:08 am

Post by live2board »

Most of the C++ basics are here so you could maybe write a tutorial on array's? Or if you wanted to get more complex maybe some vectors :twisted:. That would help me out. You could've made it atleast *look* easier by using the std namepsace, but it's still a good tutorial.
bblbuddy





Posts: 25
Joined: Fri Sep 10, 2004 6:56 pm
Location: in my happy place

Post by bblbuddy »

live2board, i would post how to do arrays but im too lazy and i forgot because the camp i went to and learned it at was like 4 months ago....oh well al i remember is its very annoying...sorry
live2board





Posts: 17
Joined: Sun Mar 27, 2005 10:08 am

Post by live2board »

Oh I don't need to know how to do arrays, I'm fairly comfortable with arrays I was just saying if you wanted to cover all the bases of the C++ basics you could do a tutorial on arrays. But a vectors tutorial on the other hand, could be quite useful.
twolvesfan369





Posts: 16
Joined: Wed Jul 20, 2005 4:15 pm

Post by twolvesfan369 »

Hm, does anyone know how to make a basic trainer. I know the offset, all i want is to change the offset value. I know how to do it with ym own program, but how do I do it to outside programs?
Post Reply