Which locale will apply to cout after cout.rdbuf(fout.rdbuf())? - c++

#include <locale>
#include <fstream>
#include <iostream>
using namespace std;
int main()
{
ofstream fout("test.txt");
fout.imbue(locale("chs"));
cout.imbue(locale("C"));
cout.rdbuf(fout.rdbuf());
cout << "中文"; // Which locale will apply to here? "C" or "chs"?
}
The question is commented in the code.

From http://www.cplusplus.com/reference/ios/ios/imbue/
std::ios::imbue <ios>
locale imbue ( const locale& loc );
Imbue locale
Associates loc to both the stream and its associated stream buffer (if
any) as the new locale object to be used with locale-sensitive
operations.
All callback functions registered with register_callback with
imbue_event as its first parameter are called.
In fact, this member function calls its inherited homonym
ios_base::imbue(loc), and if the stream is associated with a stream
buffer, also calls rdbuf()->pubimbue(loc).
Also, see http://stdcxx.apache.org/doc/stdlibug/27-4.html
27.4.4 Collaboration of Locales and Iostreams
The base class ios_base contains a locale object. The formatting and
parsing functions defined by the derived stream classes use the
numeric facets of that locale.
The class template basic_ios holds a pointer to the stream buffer.
This stream buffer has a locale object, too, usually a copy of the
same locale object used by the functions of the stream classes. The
stream buffer's input and output functions use the code conversion
facet of the attached locale.
In your case, it would use the "C" numeric locale and the "chs" character locale.

Related

Transform a buffer into an istream to work in existing programs

I am trying to create a native nodejs module, using NAN and c ++, I want to transform an existing program that uses std::ifstream stream (filename, std :: ifstream :: in | std :: ifstream :: binary); to load a file into a javascript module that can load a buffer and send it to c ++
The original c ++ code was made to work via command line, I don't want to have to write a file to disk, I would like to send this file using a nodejs buffer.
index.js
const fs = require('fs')
const addon = require('./build/Release/image_edit');
fs.readFile('image.png', function read(err, buffer) {
if (err) {
throw err;
}
var result = addon.edit(buffer, buffer.length);
//console.log(result)
});
main.cpp
#include <node.h>
#include <node_buffer.h>
#include <iostream>
#include <nan.h>
#include <sstream>
#include <string>
#include <fstream>
#include <streambuf>
#include <istream>
using namespace Nan;
using namespace v8;
uint32_t read(std::istream& in)
{
uint32_t v;
in.read(reinterpret_cast<char*>(&v), sizeof(v));
return v;
}
NAN_METHOD(edit) {
unsigned char*buffer = (unsigned char*) node::Buffer::Data(info[0]->ToObject());
unsigned int size = info[1]->Uint32Value();
//the closest I could to manipulating the data was using a vector
std::vector<uint32_t> png_data(buffer, buffer + size);
//The main core of the program uses the in.read function to parse the file, tb uses in.clear () and in.seekg ();
//here an example of how this is done
uint32_t count = readU32(stream);
}
NAN_MODULE_INIT(Init) {
Nan::Set(target, New<String>("edit").ToLocalChecked(),
GetFunction(New<FunctionTemplate>(edit)).ToLocalChecked());
}
NODE_MODULE(image_edit, Init)
I tried using the following code to verify that the data received is valid and if the recorded file is the same as the original, everything looks fine.
std::ofstream FILE("test.png", std::ios::out | std::ofstream::binary);
std::copy(png_data.begin(), png_data.end(), std::ostreambuf_iterator<char>(FILE));
The question is, how do I make this buffer received from nodejs into something read the same way an ifstream does, without having to drastically change the c ++ program?
The main methods called by the program in c ++ are: .seekg (), .push_back, .clear (),
This kind of thing is usually done by implementing a custom subclass of std::streambuf, and then using it to construct a std::istream.
std::istream has a constructor that takes a pointer to a std::streambuf as a parameter, so the basic outline is something like this
class my_streambuf : public std::streambuf {
// ... Your implementation of your subclass
};
my_streambuf msb{ /* Parameters to your class's constructor */ }
std::istream i{&msb};
At this point, i is an ordinary input stream and does everything that any other input stream does. You can seek it. You can read from it.
Of course, the hard part is implementing your custom subclass of std::streambuf. This is not something that can be fully described in one or two paragraphs on stackoverflow.com. You should read std::streambuf's documentation, specifically the descriptions of its virtual methods. Your custom subclass will need to reimplement std::streambuf's virtual methods and make them work with your buffer. It's likely you will not need to reimplement all the virtual methods. For some of them their default implementation will be sufficient. Some of them won't be needed, for what you end up doing with std::istream.
You will have to determine, based on you specific needs to what extent you need to reimplement which std::streambuf's virtual methods, and how.
Of course, another, easy alternative is to use your buffer to construct a std::string, and then using it to construct a std::istringstream, and call it a day. Of course, that'll be somewhat wasteful and require effectively doubling the memory used for the data, with a second copy that's owned by a throw-away std::string, and copying it. If this is a small amount of data that's probably fine, but if your buffer is very big that may not be practical, and a custom std::streambuf subclass that uses the buffer directly is your only option.
Like the other answer mentioned, you can use an std::stringstream if you don't want to go the std::streambuf route:
std::stringstream ss;
std::copy(png_data.begin(), png_data.end(), std::ostreambuf_iterator<uint32_t>(ss));
Then you just use it like an input stream.

What is the standard output buffer called?

When I write a filebuf, everything is ok.
I'd like to know what is called a buffer for standard output.
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
filebuf m;
m.open("/home/patryk/untitled6/text.txt", ios::out);
ostream out(&m);
out<<"to ja";
}
I don't want use e.g cout.rdbuf.
Only as above
The name of the output stream
#include <iostream>
using namespace std;
int main()
{
ostream out(cout.rdbuf());
out<<"to ja";
}
It is an implementation defined type derived from std::streambuf Here is what a popular C++ reference says:
The global objects std::cout and std::wcout control output to a stream buffer of implementation-defined type (derived from std::streambuf), associated with the standard C output stream stdout.
This means you can only realistically access the instance currently inside std::coutusing std::cout.rdbuf() - unless your compiler vendor provides non-standard access to its relevant internals.
For example, GCC provides stdio_filebuf, an instance of which could be "wrapped around" the standard output file descriptor.
In both examples, there is no need to use std::ostream the way you are.
In the first example, use std::ofstream instead of std::filebuf:
ofstream out("/home/patryk/untitled6/text.txt");
out << "to ja";
In the second example, std::cout is already a std::ostream so just write to it directly:
cout << "to ja";
In both cases, this abstracts away how the actual buffers are implemented. Just focus on the higher level stream interface by itself. The buffers used are just implementation details.

How can I reverse the output stream in c++?

What I am trying to achieve is to use the standard std::cout and if you understand, reverse the output to an input so another part of my program can read it. No I cannot just call a function in the other part of my program because every function is and must stay private so this seems the only way to do it. I did a similar thing in java by redirecting the default output stream to my own custom one but I am somewhat new to c++. This is what I did in java:
System.setOut(customPrintStream);
Does anyone know of an alternative for c++ or a way to get whatever is printed to console?
The c++ standard library supports the concept of 'reverse iterators'.
#include <iostream>
#include <string>
#include <iterator>
#include <algorithm>
int main()
{
auto s = std::string("Hello, World");
std::copy(std::rbegin(s), std::rend(s),
std::ostream_iterator<char>(std::cout));
std::cout << std::endl;
return 0;
}
expected output:
dlroW ,olleH
The streams in C++ read from and write to std::streambuf objects. You can replace the stream buffer of an std::ostream object using the rdbuf() function. For example, to capture all output written to std::cout in a std::string you could use something like this:
std::ostreamstream stream;
std::streambuf* sbuf = std::cout.rdbuf(stream.rdbuf());
// use code whose output is written to `std::cout`
std::cout.rdbuf(sbuf); // restore the original stream buffer
std::string output = stream.str();
In a real implementation you'd probably use an RAII approach to replace/restore the stream buffer. Also, you might want to use a custom stream buffer rather than a std::stringbuf but the basic remain as is.

Method parameter for both iostream and stringstream

I'd like to input a stream parameter to a method which can be either a <stringstream> or <iostream> as in:
void method(? out); // or
void method(? in);
If ? is <istream> or <ostream> it's straightforward. What I don't know is what to do if the parameter is either <istream> or <stringstream> or is either <ostream> or <stringstream>.
Can this be done?
The streams implementing both std::istream and std::ostream, e.g., std::stringstream and std::fstream derive from std::iostream (since they are all class templates, you'd look for basic_... in the standard). That is, if you really need a stream which is used for both input and output, you'd pass an std::iostream&.
The class std::iostream derives from both std::istream and std::ostream. The appropriate types are straight forward:
for reading only use std::istream&
for writing only use std::ostream&
for reading and writing use std::iostream& (I don't think I ever used this in production code)
Note that you need to seek when switching between reading and writing in case the stream may be a file stream: switching between reading and writing without intervening seek, even if the seek is to the current position, results in undefined behavior.
Both the string stream classes and file stream classes publically-derive from the general stream bases classes std::basic_istream<...> and std::basic_ostream<...>. This means that you can pass (for instance) std::ostringstream objects to functions that take std::ostream:
void test(std::ostream& os);
std::ostringstream buf;
test(buf); // Good!
Unless of course, you need additional functionality specific to the derived stream classes. For example, string streams provide an str() method and file streams provide open()/close() member functions. In the case where you need these, you can have test() take string streams or file streams as parameters.
void test(std::istringstream& iss)
{
std::cout << iss.str(); // Works because the type is a stringstream
}

Solving an exercise from Thinking C++

The exercise says:
Create a Text class that contains a string object to hold the text of
a file. Give it two constructors: a default constructor and a
constructor that takes a string argument that is the name of the file
to open. When the second constructor is used, open the file and read
the contents into the string member object. Add a member function
contents() to return the string so (for example) it can be printed. In
main( ), open a file using Text and print the contents.
This is the class that I wrote:
class Text {
string fcontent;
public:
Text();
Text(string fname);
~Text();
string contents();
};
I haven't understood everything of this exercise. It asks to create a function contents(), that returns a string, but it doesn't says what the function has to do...
Neither what the default constructor has to do.
Could someone help me?
The function has to return the contents of the file, which is stored (in your case) in fcontents.
string Text::contents()
{
return fcontent;
}
The default constructor doesn't have to do anything in this case.
Text::Text(){}
EDIT:
Seeing how many comments there are below with new problems, I'm going to recap and answer the rest of the questions here.
in Text.h you have:
#ifndef TEXT_HH
#define TEXT_HH
#include <string> //[1]
class Text {
std::string fcontent;//[2]
public:
Text();
Text(std::string fname);
~Text();
std::string contents();
};
#endif
and Text.cpp has
// Text.cpp
#include "Text.h"
#include <fstream>
#include <iostream>
#include <sstream>
#include <string>
using namespace std;
Text::Text() {}
Text::Text(string fname) {
fstream f;
f.open(fname.c_str(), ios::in);//[3]
//[4]
std::stringstream stream;
while(true)
{
char buffer[1000];
f.getline(buffer, 1000);
if(f.good())
{
//This actually adds an extra newline at the end
stream << buffer << '\n';
}
else
{
break;
}
}
fcontent = stream.str();
//remove extra newline
fcontent.erase(fcontent.begin() + fcontent.size() - 1);
f.close();//This is technically unnecessary, but not bad either
}
string Text::contents() {
return fcontent;
}
Text::~Text() {}//[5]
Point 1: The header file <string> contains the class definition for std::string, the C++ string. This should not be confused with <cstring> which contains functions for manipulating C strings (const char *, const char[], etc).
Point 2: The string class exists in the ::std namespace, which means we have to either use std::string every time we want that class or use using namespace std; to pull this class into the global scope. In the header file we prefer the former method because the using declaration doesn't go away, which means that the namespace will be changed for every header and source file that includes this one, which we want to avoid in general (ie. always). In the cpp file however, there is no problem using the using declaration and we do so.
Point 3: fstreams take a C string as the filename parameter, we can get the corresponding C string from a C++ string with the call c_str(). This returns a const char *.
Point 4: To read the whole text file into a string is less obvious than it seems because the way streams deal with eof (end-of-file) and state-checking stuff. In short it will read one more time than you want it to (I know, wanting is subjective, but is close enough I think) before setting the eof flag. That's why the state is checked after calling get and before adding what's been read to our stringstream. Streams are a fairly elaborate topic so I won't go into it in more detail here.
Point 5: Destructors on objects (non-pointers, like our fcontents is) are called automatically, so we don't need to do anything to make sure that our fcontents string is destroyed when our Text object is destroyed. When we allocate something dynamically with new that's when we have to worry about calling delete on it when we want to destroy it.