I have a coursework to submit and I almost finished it all. But I'm stuck in
a bit where I have to read a class instance to a file using output stream operator. the output stream operator takes instance as an argument but I need
to use it for a pointer to an instance. any help please?
My output stream operator implementation is:
ostream& operator<<(ostream& out, sequence &s)
{
out<<s.number_of_samples;//<<s.samples;
s.samples=new float [s.number_of_samples];
for(int i=0; i<s.number_of_samples; i++) out<<s.samples[i];
return(out);
}
The bit where it reads the instance to a file is:
ofstream output_filtered_samples_file("output.txt");
sequence* filtered_sequence = test_FIR.apply_filter(test_sequence);
output_filtered_samples_file<<filtered_sequence;
Full code is http://ideone.com/V0Xavo
Dereference the pointer . . .
output_filtered_samples_file<<*filtered_sequence;
You have two options:
Write an operator<<() that accepts a pointer
Pass the dereferenced value.
The second option is probably best:
output_filtered_samples_file << *filtered_sequence;
Your operator<<() should prefer to accept a reference to const, as nobody expects it to modify the object:
ostream& operator<<(ostream& out, const sequence &s)
This will help you identify what's wrong with the body of the method.
Related
I am working on my assignment and need help in completing the following function. I have been provided with the following signature:
void merge(const std::vector<istream>& inputStreams, ostream& o);
The function is supposed to take k integer streams as input and sort them and store the result in an ostream object.
I have completed the function definition but the problem is I cannot test the function by providing it the input (ie: vector of istream objects). If I try to pass the function a vector of istream objects, the compiler throws too many errors for me to debug.
Here is the function definition:
void merge( vector<istream>& inputStreams, ostream& o){
vector<long long int> input_vec;
long long int input_vec_size = inputStreams.size();
for(int i=0; i<input_vec_size;i++)
{
long long int temp;
while(inputStreams[i]>>temp)
{
input_vec.push_back(temp);
}
}
sort(input_vec.begin(),input_vec.end());
for(int i=0;i<input_vec.size();i++)
{
o<<input_vec[i];
}
}
And to pass a vector of istream objects i did the following:
int main()
{
//ifstream a1,a2,a3,a4;
filebuf fb1,fb2,fb3;
fb1.open("fb1.txt",ios::in);
fb2.open("fb2.txt",ios::in);
fb3.open("fb3.txt",ios::out);
istream a1(&fb1);
istream a2(&fb2);
ostream out(&fb3);
vector<istream> inp;
inp.push_back(a1);
inp.push_back(a2);
merge(inp,out);
}
can anyone help me?
For starters, it's fairly unusual to see the type istream being used as the actual type of an object. The reason for this is that istream is meant to be used as a base class, and those base classes are what more often get used. For example, you'll see variables of type istringstream or type ifstream much more regularly than just plain old istream. It's not wrong, per se, to have a variable that's an honest-to-goodness istream, but it is unusual.
Typically, if you wanted to work with a function that manipulated some sort of input stream, you'd structure it so that it either took in a reference to the istream or a pointer to the istream. That's the general C++ way of handling polymorphic types.
In your case, the fact that you're trying to use a vector<istream>, regardless of whether the code will compile or not, should therefore make you pause a minute to think about whether you're doing the right thing. It's entirely possible that, yes, you indeed do have a bunch of istream objects, and those objects aren't istringstreams or ifstreams. But more probably, what you were aiming to do here was say "I take in some list of input streams, and I don't really care what kind of input streams they are as long as they inherit from istream."
If that's what you're hoping to do, there are several ways you could address this. Perhaps the easiest is to change vector<istream> to vector<istream *> (or perhaps vector<shared_ptr<istream>>, depending on context). That would mean "I'd like to take as input a list of streams, and since I can't say for certain what specific type each of those streams will be, I'll just have the client give me pointers to each of them." That's going to require you to make some changes to your code so that, as you access the elements of the vector, you treat them as pointers rather than as actual, honest-to-goodness istream objects. For example, the line
while (inputStreams[i] >> temp) { ... }
might need to get rewritten as
while (*inputstreams[i] >> temp) { ... }
to explicitly dereference the pointer.
The other question you asked was how to test this code at all, and that's a separate step. Remember, it's fairly unusual to create objects of type istream, so you'd probably want to make either objects of type istringstream or ifstream. Here's an example of how you might make a few streams and then pass them into your function:
istringstream stream1("137 2718");
istringstream stream2("27 182 818");
istringstream stream3("3 14 15 92 653");
merge({ &stream1, &stream2, &stream3 }, cout);
Here, rather than declaring a local variable of type vector<istream *>, we just use a brace-initializer to say "please make me a vector out of these pointers."
From the sample code you've provided it looks like you want to read data from a bunch of files. Here's how you might do that. Rather than making filebuf objects and wrapping them in istreams, which is legal but fairly uncommon, we'll just use ifstream:
ifstream stream1("fb1.txt");
ifstream stream2("fb2.txt");
ifstream stream3("fb3.txt");
vector<istream *> inputs;
inputs.push_back(&stream1);
inputs.push_back(&stream2);
inputs.push_back(&stream3);
merge(inputs, cout);
Hope this helps!
istream is not copyable or moveable, hence you can't make a vector of istreams. Try using std::vector <std::istream *> instead (and modify your code accordingly).
Live demo: https://wandbox.org/permlink/20I2VQqsRI8ofaxP
I've been working on a personal dictionary application which can help you remembering words you learnt. It is operated via the CLI (just don't question this, it's kinda just a test and I got a weird passion for CLI apps). So, of course I am using ostreams for writing information on the CLI. I am used to write operator<< overloads (for ostreams) for every class so that I can build up a multi-level output system (basically every object can "speak" for itself).
In order to persist a dictionary object, I wanted to use ofstream and write a file with it. Naturally, I wrote operator<< overloads also for ofstream and in the same "layered" structure.
As a result, I have now two operator<< overloads in every class, like in "Dictionary":
ostream& operator<<(ostream&, const Dictionary&);
ofstream& operator<<(ofstream&, const Dictionary&);
(this is just the declaration in the header file)
Notice that it is very important that these both overloads do different things. I don't want to have some weird persistence-oriented special-format text on the CLI and also not user-friendly plain text in my file.
The problem is that, because of the inheritance structure of ostream and ofstream, ofstream is sometimes implicitely converted to ostream. And when this happens in the middle of my stack full of file output operations, the program suddenly jumps into the wrong overload and prints plain text in the file.
My question is simply: Is there a way to avoid or revert these unwanted implicit conversions in order to let my program jump into the right overloads? Or is there any other good way to fix this problem?
EDIT 1:
Someone pointed out in the comments that this is not an implicit converison. ofstream is sometimes "seen" as its base class ostream. The problem is that at some point the object "forgets" that it is an ofstream and loses all file-related information. From there on it is only an ostream and that's what I meant with the "conversion".
EDIT 2:
The exact point in the program where the "unwanted conversion" happens can be found here:
ofstream& operator<<(ofstream& of, const Section& s) {
return s.print_ofstream(of);
}
So this operator overoad calls "print_ofstream":
ofstream& Section::print_ofstream(ofstream& of) const {
of << "sec" << Util::ID_TO_STRING(section_id) << ":\n";
for (pair<Wordlist, Wordlist> pwl : translations) {
of << '{' << pwl.first << '=' << pwl.second << "}\n";
}
of << "#\n";
return of;
}
Note that "pwl" is a pair of two Wordlists, therefore pwl.first / pwl.second is a Wordlist. So, normally the line of << '{' << pwl.first << '=' << pwl.second << "}\n"; should call the ofstream operator<< overload in Wordlist. But it doesn't. Instead, the other overload method is called:
ostream& operator<<(ostream& o, const Wordlist& wl) {
return wl.print_ostream(o);
}
You have overloaded only the specific operator<< needed for streaming Dictionary, Section, Wordlist, etc objects to a std::ofstream, but std::ofstream inherits MANY other operator<<s from std::ostream, and those operators all take ostream& as input and return ostream& as output. So, for example, of << "sec" will return ostream& even though of is a std::ofstream, and then that ostream& is used for subsequent << calls until ; is reached. Those are the "implicit conversions" you are experiencing.
The real question is, WHY do you want operator<< to output different data depending on the type of std::ostream being written to? That goes against C++'s streaming model. If you really want that, you would have to change print_ofstream(ofstream&) to print_ostream(ostream&) and then dynamically detect the actual std::ostream derived type using dynamic_cast. Same with Wordlist, and any other classes that need it.
A simpler and safer option would be to just store a flag inside of your classes to control how their data should be output, regardless of the type of std::ostream being used. Then you can set that flag as needed. Maybe even define some helper I/O manipulators to set those flags while making << calls.
I'm working on a school project to implement a c++ class for polynomials. Something my class is supposed to do is read polynomials from standard in, or from a file. I thought about overloading >> until I read the following on my favorite c++ reference site:
Notice that the istream extraction operations use whitespaces as
separators, therefore this operation will only extract what can be
considered a word from the stream. To extract entire lines of text,
refer to the string overload of global function getline.
This got me all inspired to overload the global function getline for my polynomial class so that it can read whole lines from a file. There are lots of tutorials and articles describing how to overload the stream extraction operator, but I couldn't find any details about getline. Should I just overload it however I want? From the reference this appears to be how it's done.
In some of the overloaded getline functions I've seen (such as at the bottom of the page linked to), I noticed they return something like "basic_istream". Is it enough that I just return istream? What about for "char_type"? Would char suffice?
Basically I want to know: is this one of those anything goes overloads, or is there some finicky detail I should be worried about?
This is the header I've cooked up:
class Polynomial {
public:
friend istream& getline(istream& is, Polynomial & poly);
friend istream& getline(istream& is, Polynomial & poly, char delim);
};
friend istream& getline(istream& is, Polynomial & poly) {
return getline(is, poly, '\n');
}
friend istream& getline(istream& is, Polynomial & poly, char delim) {
// read enough tokens to make a term
// stop when we get to the delimiter
return is;
}
Thanks!
You should still overload operator >>. Within your operator implementation, you can extract as many 'words' as you need (I'm assuming one per coefficient or so). Don't try to overload getline, thats about getting a line not a Polynomial.
I am still confused about the difference between ostream& write ( const char* s , streamsize n ) in c++ and cout in c++
The first function writes the block of data pointed by s, with a size of n characters, into the output buffer. The characters are written sequentially until n have been written.
whereas cout is an object of class ostream that represents the standard output stream. It corresponds to the cstdio stream stdout.
Can anyone clearly bring out the differences between the two functions.
ostream& write ( const char* s , streamsize n );
Is an Unformatted output function and what is written is not necessarily a c-string, therefore any null-character found in the array s is copied to the destination and does not end the writing process.
cout is an object of class ostream that represents the standard output stream.
It can write characters either as formatted data using for example the insertion operator ostream::operator<< or as Unformatted data using the write member function.
You are asking what is the difference between a class member function and an instance of the class? cout is an ostream and has a write() method.
As to the difference between cout << "Some string" and cout.write("Some string", 11): It does the same, << might be a tiny bit slower since write() can be optimized as it knows the length of the string in advance. On the other hand, << looks nice and can be used with many types, such as numbers. You can write cout << 5;, but not cout.write(5).
cout is not a function. Like you said, it is an object of class ostream. And as an object of that class, it possesses the write function, which can be called like this:
cout.write(source,size);
"In binary files, to input and output data with the extraction and insertion operators (<< and >>) and functions like getline is not efficient, since we do not need to format any data, and data may not use the separation codes used by text files to separate elements (like space, newline, etc...).
File streams include two member functions specifically designed to input and output binary data sequentially: write and read. The first one (write) is a member function of ostream inherited by ofstream. And read is a member function of istream that is inherited by ifstream. Objects of class fstream have both members. Their prototypes are:
write ( memory_block, size );
read ( memory_block, size );
"
from: http://www.cplusplus.com/doc/tutorial/files/
There is no function ostream& write ( const char* s , streamsize n ). Perhaps you are referring to the member function ostream& ostream::write ( const char* s , streamsize n )?
The .write() function is called raw (or unformatted) output. It simply outputs a series of bytes into the stream.
The global variable cout is one instance of class ofstream and has the .write() method. However, cout is typically used for formatted output, such as:
string username = "Poulami";
cout << "Username: '" << username << "'." << endl;
Many different types have the ostream& operator<<(ostream& stream, const UserDefinedType& data), which can be overloaded to enrich ofstream's vocabulary.
Oh boy! A chance to smash up a question.
From your question I feel you are some Java or Python programmer and definitely not a begginner.
You dont understand that C++ is probably the only language that allows programmers to implement primitive built in operators as class members and as part of the general interface.
In Java you could never go
class Money
{
int operator + (int cash) { return this.cash + cash; }
void operator << () { System.out.println(cash); }
int cash;
}
public class Main_
{
public static void Main(String [] args)
{
Money cashOnHand;
System << cashOnHand;
}
}
But cpp allows this with great effect. class std::ostream implements the stream operators but also implements a regular write function which does raw binary operations.
I agreed with Alok Saveļ¼A litte before, I searched the problem and read the answer carefully.
Maybe in other word, cout is an object of ostream, but write is just a function provided. So cout have twe ways to used by coders: one is as a member function, another is used by operator(<<).
i have an overloaded operator << trying to make it work like this
mystream<<hex<<10;
i have overloaded method
mytream& operator<<(ios_base& (*m) ios_base&)
This gets called whenever hex is encountered cause the parameter passed in the method is a function pointer of type same as hex or like some other output manipulators like dec, oct.
i have two problems
1) how do i retrieve the parameter the hex would be operating on, in this example 10
2) how do i know that the << operator is being called for hex and not other manipulator function like oct and dec
Thanks
1) hex is not operating on the parameter 10. << operators associate left-to-right, which means your code is the same as:
(mystream<<hex)<<10;
So your overload has to return an object which, when 10 is shifted into it, prints in hex (or if not prints, writes data somewhere). As everyone says, this is done by saving flags in the stream object itself, then returning *this. The reason flags are used is precisely because the "10" is not available yet, since the second << has not been evaluated yet. The first << operator call cannot print anything - it just has to get ready for when the second one is called.
2) hex is a function. It can be compared with other functions:
ostream &operator<<(ostream &s, ios_base& (*m)(ios_base &)) {
if (m == hex) {
} else if (m == oct) {
} else if (m == dec) {
}
}
Except you don't normally want to do that, you want the default behaviour, which is something like:
ostream &operator<<(ostream &s, ios_base& (*m)(ios_base &)) {
return m(s);
}
(I may be wrong on that, I've never looked at the implementation, but the general idea is that the operator calls the manipulator function, and the manipulator (the clue's in the name) manipulates the stream).
std::hex sets the std::ios::hex format flag on its parameter. Then in your operator<<(int) override, if you have one, check the format flags by calling flags().
3) Manipulators which take paramers are functions too, but their return types are unspecified, meaning it's up to the implementation. Looking at my gcc iomanip header, setw returns _Setw, setprecision returns _Setprecision, and so on. The Apache library does it differently, more like the no-args manipulators. The only thing you can portably do with parameterized manipulators is apply them to an iostream with operator<<, they have no defined member functions or operators of their own.
So just like hex, to handle setw you should inherit from std::ios_base, rely on the operator<< implementation provided by your library, then when you come to format your data, examine your own width, precision, etc, using the width(), precision(), etc, functions on ios_base.
That said, if for some bizarre reason you needed to intercept the standard operator<< for these manipulators, you could probably bodge something together, along these lines:
template <typename SManip>
mystream &operator<<(mystream &s, SManip m) {
stringstream ss;
// set the state of ss to match that of s
ss.width(s.width());
ss.precision(s.precision());
// etc
ss << m;
// set the state of s to match that of ss
s.width(ss.width());
s.precision(ss.precision());
// etc
return s;
}
I do consider this a bodge, though. You're not really supposed to interfere with stream manipulators, just let your base class do the work and look up the results.
When operator<< gets called with hex or oct or dec, set a flag in your mystream object. When operator<< is called with a number, check to see if any of these flags are set. If so, convert the number to hex/octal/decimal and display it.
In answer to your second question, the parameter m is a pointer to the manipulator function. You can check that it's not null, then call that function, passing *this. hex() is as simple as setting a flag in the passed stream object, as Zifre suggested. Then when processing the integer, check if the flag in the stream object is set, and output accordingly.
This is how the standard library implements its manipulator functions.
In your example, hex operates on (changes the state of) the stream, not the following parameters. hex has no notion of, or any relation to other << calls.
Looking at how other io manipulators are implemented would go a long way to clearing things up.
You should be manipulating ios_base::flags
http://www.cplusplus.com/reference/iostream/ios_base/flags/
which is what the standard hex does.