understanding the code - c++

Can some one explain me this code
there is a class StringStream . What i don't get is StringStream& write(char*).
and if in cpp file there is
StringStream& StringStream::write(char* text)
{
//what values can i return??
//can i return address of character text is currently pointing to?
}

You'd return *this - i.e. a reference to the current object. (Well, you can return any non-local StringStream, but I guess the purpose is the one I stated)
This technique is usually used for method chaining - i.e. doing something like:
StringStream ss;
ss.write("Hello ").write("world!");

This is a method that most likely modifies a StringStream instance, and returns a reference to a StringStream. So you should return a reference to the instance itself
StringStream& StringStream::write(char* text)
{
// do stuff
return *this;
}
This allows you to perform chaining:
StringStream s;
s.write("foo").write("bar");
That said, I would have expected the write method to take a const char*:
StringStream& write(const char* text);
since the method will presumably not modify the data passed to it, and is required in order to be able to correctly pass string literals such as the "foo" and "bar" in the example.

you can simply return a reference to stringStream class. As you are writing a member function of the same class you can simply return pointer to this. For more info about the StringStream class : click here

Related

I need to access the value within a const std::string& call in a function

I have a quick question regarding C++ and references to values. I have been asked to write a function that takes the input from const std::string& and use the input to perform some tasks. The issue is, I have no idea how to access the value. I know it is a pass-by reference value but I don't know how to access it within the function.
This is the code that I was given:
#include "rle.hpp"
std::string func_send(const std::string&)
{
//Implement !
return {};
}
std::string func_receive(const std::string&)
{
// Implement!
return {};
}
The code you were given makes no sense, at least there is no way to acces the parameter because it has no name. Moreover std::string str = std::string&; is invalid syntax, I don't know what it is supposed to mean. Give the parameter a name:
std::string func_send(const std::string& str)
// ^------------ !!!
{
std::string some_other_string = str;
return {}; // missing semi-colon
}

Avoiding having static const variables everywhere

I have the below code in a C wrapper to a C++ class. I need to return the string value of the response from my json::value object. The problem is, using c_str() returns a pointer that is destroyed at the end of the function. Thus I have the below horrendous and unsafe code:-
const char* const response_Json(CResponse *resp) {
using namespace myclient;
Response *t = (Response*)resp;
const web::json::value& json = t->Json(); // NOTE: Json() can ONLY be called ONCE
std::ostringstream stream;
stream << json; // REQUIRED to get raw JSON as text, as serialize(void) does NOT work
//t->Json().serialize(stream); // Doesn't work - blank result
std::string asstr = stream.str();
static const std::string& statref = stream.str(); // REQUIRED to ensure reference to string, and thus contained c_str, is not destroyed
static const char* pref = statref.c_str(); // REQUIRED so we have a local char pointer that is not temporary, and thus destroyed at function's exit
return pref;
}
I've found that both statref and pref are required to be declared as static const in order for a value to actually be returned rather than a hanging pointer (I.e. static const's required up the whole object graph to asstr) but I'm not sure why. I would have thought the one for pref would have sufficed.
I'd like to remove all static variables as this function will be called multiple times, and perhaps in parallel.
What I need to do is return the C char*, or a copy thereof, that avoids the use of static const. I've been searching for days and can't find the answer anywhere.
The conclusion I've come to is that I need to pass in a char* that this function modifies, rather than returns.
You need to pass a buffer to the response_Json function and that function should copy the string into the buffer the caller provides.
Basially you need this:
void const response_Json(CResponse *resp, char *buffer) {
using namespace myclient;
Response *t = (Response*)resp;
const web::json::value& json = t->Json(); // NOTE: Json() can ONLY be called ONCE
std::ostringstream stream;
stream << json; // REQUIRED to get raw JSON as text, as serialize(void) does NOT work
//t->Json().serialize(stream); // Doesn't work - blank result
std::string asstr = stream.str();
strcpy(buffer, asstr.c_str);
}
For the sake of simplicity no buffer overrun checking is done here.
Maybe there is still room for improvement in the json stuff section of the function.

Initializing "const std::string" from "std::istringstream"

I'm trying to parse a file which is in Key<whitespace>Value format. I'm reading the file lines in an std::istringstream object, and I'm extracting a Key string from it. I want to avoid accidentally changing the value of this Key string by making it const.
My best attempt was initializing a temporary VariableKey object, and then making a constant one out of it.
std::ifstream FileStream(FileLocation);
std::string FileLine;
while (std::getline(FileStream, FileLine))
{
std::istringstream iss(FileLine);
std::string VariableKey;
iss >> VariableKey;
const std::string Key(std::move(VariableKey));
// ...
// A very long and complex parsing algorithm
// which uses `Key` in a lot of places.
// ...
}
How do I directly initialize a constant Key string object?
It's arguably better to separate file I/O from processing, and instead of creating a const Key inside the same function - call a line-processing function that takes a const std::string& key parameter.
That said, if you want to continue with your current model, you can simply use:
const std::string& Key = VariableKey;
There's no need to copy or move anything anywhere. Only const std::string members functions will be accessible via Key.
You can avoid the "scratch" variable by extracting the input into a function:
std::string get_string(std::istream& is)
{
std::string s;
is >> s;
return s;
}
// ...
while (std::getline(FileStream, FileLine))
{
std::istringstream iss(FileLine);
const std::string& Key = get_string(iss);
// ...
(Binding the function's result to a const reference extends its lifetime.)

Trying to return std::ifstream from a function

When I try to use this function I get a error at the two returns. If I comment them out I do not get the errors. Is there any reason why this should not work?
std::ifstream bipgetConfigurationPath() {
char bipacfFilename[256], bipacfFullPath[512];
char *bipconfigPath;
char *bipdefaultConfigFile;
const char *bipdefaultConfigFileName;
bipdefaultConfigFile = "./Resources/plugins/Xsaitekpanels/D2B_config.txt";
bipdefaultConfigFileName = "D2B_config.txt";
XPLMGetNthAircraftModel(0, bipacfFilename, bipacfFullPath);
bipconfigPath = strstr(bipacfFullPath, bipacfFilename);
strncpy(bipconfigPath, bipdefaultConfigFileName, sizeof(bipacfFilename));
puts(bipacfFullPath);
// Check if ACF-specific configuration exists
std::ifstream bipcustomStream(bipacfFullPath);
if (bipcustomStream.good()) {
return bipcustomStream;
} else {
std::ifstream bipdefaultStream(bipdefaultConfigFile);
if (bipdefaultStream.good()) {
return bipdefaultStream;
}
}
}
Thanks Bill
std::streams are not copyable.
All the stream classes in C++ are made noncopyable by having made their copy-constructor private. That means, you cannot return stream objects by value. Read this for detail. End of the story.
So the solution is to pass a stream object to the function as reference, and open the file in the function, and return from it, or create the stream object using new and return the pointer to the stream object from the function, but then if you do so, you've to delete the object when you're done with it. I personally would not do either of them.
I will probably encapsulate the stream and the behaviour/work you would like to do with the object, in a class.
In C++11, you can use std::move to move the stream object, as streams are movable.
As others have said file streams are not copyable. Maybe something more like this:
bool bipgetConfigurationPath(std::ifstream& ifs) {
std::string bipdefaultConfigFileName("D2B_config.txt");
// ...
ifs.open(bipdefaultConfigFileName);
return ifs.good();
}

l-value substr method in C++

I want to create a substr method in C++ in a string class that I made.
The string class is based on C-style string of course, and I take care of the memory management.
I want to write a substr(start, length) function that can work on the regular way:
CustomString mystring = "Hello";
cout << mystring.substr(0,2); // will print "He"
And also in this way:
mystring.substr(1,3) = "DD"; // mystring will be "HDDo"
Notice that even though I get a 3 chars long sub-string, I put in the assignment only 2 chars and the output string will be HDDo, still.
Any idea how to get this done?
Thanks!
To support that, you'll probably have to write your substr() to return a proxy object that keeps track of what part of the original string is being referred to. The proxy object will overload operator=, and in it will replace the referred-to substring with the newly assigned one.
Edit in response to comments: the idea of a proxy is that it's similar enough to the class for which it's a proxy that returning a proxy is still a closed operation -- i.e. from the user's viewpoint, all that's visible is the original type of object, but it has capabilities that wouldn't be possible (or would be much more difficult to implement) without the proxy. In this case, we the proxy class would be private to the string class, so the user could never create an instance of the proxy class except as a temporary. That temporary can be used to modify its parent string if you assign to it. Using the proxy in any other way just yields a string.
As to what this buys you over attempting to do it all inside the original string: each proxy object is a temporary object -- the compiler can/will/does keep track of how to create temporaries as needed, destroys them properly at the end of a full expression, etc. The compiler also keeps track of what substring a particular assignment refers to, automatically converts one to a string when we try to use its value, and so on. Simply put, the compiler handles nearly all the hard work involved.
Here's some working code. The surrounding string class is pretty minimal (e.g. it has no searching capability). I'd expect to add a fair amount to a useful version of the string class. The proxy class, however, is complete -- I wouldn't expect to see it change much (if at all) in a feature-complete version of the string class.
#include <vector>
#include <algorithm>
#include <iostream>
#include <iterator>
class string {
std::vector<char> data;
public:
string(char const *init) {
data.clear();
data.assign(init, init+strlen(init));
}
string(string const &s, size_t pos, size_t len) {
data.assign(s.data.begin()+pos, s.data.begin()+pos+len);
}
friend class proxy;
class proxy {
string &parent;
size_t pos;
size_t length;
public:
proxy(string &s, size_t start, size_t len) : parent(s), pos(start), length(len) {}
operator string() { return string(parent, pos, length); }
proxy &operator=(string const &val) {
parent.data.erase(parent.data.begin()+pos, parent.data.begin()+pos+length);
parent.data.insert(parent.data.begin()+pos, val.data.begin(), val.data.end());
return *this;
}
};
proxy substr(size_t start, size_t len) {
return proxy(*this, start, len);
}
friend std::ostream &operator<<(std::ostream &os, string const &s) {
std::copy(s.data.begin(), s.data.end(), std::ostream_iterator<char>(os));
return os;
}
};
#ifdef TEST
int main() {
string x("Hello");
std::cout << x << std::endl;
std::cout << x.substr(2, 3) << std::endl;
x.substr(2, 3) = "DD";
std::cout << x << std::endl;
return 0;
}
#endif
Edit 2:
As far as substrings of substrings go, it depends. The one situation that's not currently covered is if you want to assign to a substring of a substring, and have it affect the original string. If you want something like x=y.substr(1,4).substr(1,2); it'll work fine as-is. The first proxy will be converted to a string, and the second substr will be invoked on that string.
If you want: x.substr(1,4).substr(1,2) = "whatever"; it won't currently work. I'm not sure it accomplishes much, but on the assumption that it does, the addition to support it is fairly minimal -- you'd add a substr member to proxy:
proxy substr(size_t start, size_t len) {
return proxy(parent, pos+start, len);
}
Presumably you want substr to return a string, rather than some other proxy class. You'd therefore need to make your string class capable of holding a pointer to its own copy of the string data and also a pointer to another string object that it was created from (as the return value of substr), along with information about which part of the string it was created from.
This might get quite complicated when you call substr on a string returned from another call to substr.
The complexity is probably not worth the attractiveness of the interface.
The first requirement is simple; look up operator's standard implementation.
Loosely, c_string& substr(int, int)
The second part, not so much, I don't think. It'll look similar, I believe. However, I'll think about it and get back to you over the weekend.