Cant use std::istream::get - c++

I want use the 6th implementation of std::istream::get(...) method.
https://en.cppreference.com/w/cpp/io/basic_istream/get
It takes basic_streambuf& and char_type. I write:
char quote = '\'';
std::stringstream str;
input.get(str, quote); //input is std::istream object
But compiler as if it doesn't see this implementation, it try convert stringstream to char*:
error C2664: 'std::basic_istream<char,std::char_traits> &std::basic_istream<char,std::char_traits>::get(_Elem *,std::streamsize)': cannot convert argument 1 from 'std::stringstream' to '_Elem *'
Couldn't find answer for this. What's wrong? Thanks for help

To get the streambuf associated with a std::stringstream, you need to call rdbuf().
input.get(*str.rdbuf(), quote);

Related

left operand has type 'std::stringstream (__cdecl *)(std::string)'

what the diff in two codes blow:
char buf[2048];
stringstream in(string(buf));
int tmpInt;
while ((in >> tmpInt)) { // wrong, error C2296: '>>' : illegal, left operand has type 'std::stringstream (__cdecl *)(std::string)'
}
and
char buf[2048];
string tmpStr(buf);
stringstream in(tmpStr);
while ((in >> tmpInt)) { // right
}
I think they do same thing: both use string to construct a stringstream object. No matter temp object or a real object, we will call string copy constructor in stringstream(just copy buf content)
IDE: vs2010
So, what the different between this two ways ? or stringstream implement ways .
thanks.
Chris gave away the answer. The code is the equivalent of the following:
stringstream in(string buf);
In C++, people call this the most vexing parse.
The compiler sees it as a function declaration. in is a function which returns a stringstream and accepts a string as an argument. Note that your compiler is telling you this in the error message std::stringstream (__cdecl *)(std::string).
You will need an extra set of parentheses or C++11 uniform initializer syntax to tell the compiler its not a function you are declaring:
stringstream in((string(buf)));
stringstream in{string(buf)};

Mixing DEFINEs with Literal Strings in C++

I've created a #define which points to a particular directory. I would then like to use this definition in combination with a string literal:
#define PATH_RESOURCES "/path/to/resources/"
std::ifstream datafile(PATH_RESOURCES + "textures.dat");
However, the compiler complains about adding char types using the + operator:
error: invalid operands of types ‘const char [11]’ and ‘const char [13]’ to binary ‘operator+’
So how can I combine a #define with a string literal? Or, is there a better way of doing this altogether? I imagine using a const variable would be an alternative, but this would mean having to pass around yet another parameter which I'd rather prefer to keep as a global definition.
You can combine two string literals by writing them one after the other with no + plus between them:
std::ifstream datafile(PATH_RESOURCES "textures.dat");
The fact that one of the string literals happens to be defined through the preprocessor does not change much: you can do it like this as well:
std::ifstream datafile(PATH_"/path/to/resources/" "textures.dat");
Here is a demo on ideone.
Try
std::ifstream datafile(PATH_RESOURCES "textures.dat");
Two string literals adjacent concatenate.
Use std::ifstream datafile(PATH_RESOURCES "textures.data");
Note the lack of the + operator.
You could also do
std::ifstream datafile(std::string(PATH_RESOURCES) + std::string("textures.data")); if you really wanted.
Create a std::string, assign your #define string to it and add the second literal. Afterwards use the string.
std::string str(PATH_RESOURCES);
str = str + "textures.dat";
std::ifstream datafile(str);

Inconsistent stringstream errors

I'm having bizarre behavior with stringstreams. It seems that if I create two stringstreams, one will write correctly and one will raise errors. (test is a char*)
ostringstream s;
ostringstream d;
s<<test<<endl;
d<<test<<endl;
This gives the message "error: invalid operands of types 'int' and 'const char*' to binary 'operator<<'" for the last line.
ostringstream s;
ostringstream d;
d<<test<<endl;
d<<test<<endl;
This gives the message "error: invalid operands of types 'int' and 'const char*' to binary 'operator<<'" for both lines writing to d.
The two streams should be identical, so I don't know why d doesn't work. Switching the order of the declarations of s and d doesn't change anything. Anyone have an ideas why this might happen?
Thanks!
I have the same error when the variable d has already been declared so it has another type.

Write to user specified file in C++

Can I specify what file I want to write into in C++? I want to be able to type in the filename and write into that file. When I try making myfile.open("example.txt") myfile.open(var), I get a big error...
error: no matching function for call to ‘std::basic_ofstream >::open(std::string&)’
/usr/include/c++/4.2.1/fstream:650: note: candidates are: void std::basic_ofstream<_CharT, _Traits>::open(const char*, std::_Ios_Openmode) [with _CharT = char, _Traits = std::char_traits]
Can you make any sense of this or explain what I am doing wrong? I have a feeling this is very simple, as this is my first week using C++.
If var is an std::string, try:
myfile.open(var.c_str());
The error tells you exactly what's wrong, although the precision of the template types named doesn't help make that crystal clear. Take a look at the reference for .open(). It takes a const char * for the filename, and another optional mode parameter. What you are passing is not a const char *.
Like the error says, it is trying to match the parameters with a character pointer and std::string is not a character pointer. However std::string::c_str() will return one.
try:
myfile.open(var.c_str());
In short, yes you can specify a file to open and write into many different ways.
If you're using an fstream and want to write plain text out, this is one way:
#include <string>
#include <fstream>
int main()
{
std::string filename = "myfile.txt";
std::fstream outfile;
outfile.open( filename.c_str(), std::ios::out );
outfile << "writing text out.\n";
outfile.close();
return 0;
}
Is var a std::string? If so, you should be passing var.c_str() as there is not a variant of .open() that takes a std::string.
Is your variable a string, char[], or char*? I think the open() method wants a c-style string, which would be char[] or char*, so you'd need to call the .c_str() method on your string when you pass it in:
myfile.open(var.c_str());
There is a second parameter to the open call. it should be like myfile.open("example.txt", fstream::out)
The error message is quite clear. It says: the basic_ofstream class (your file object) does not have a member function that's called "open" and takes a single argument of type string (your var). You need to go from string to const char * - for that, you use var.c_str().

Alternative to lexical_cast<T>(std::string)

I've got templated code that uses lexical_cast.
Now I want to remove all the lexical_cast calls (because it doesn't work well with /clr).
I need to cast object between std::string and their value.
So, the first direction is easy (T _from, std::string _to) :
std::ostringstream os;
os << _from;
_to = os.str();
But I can't think of a way to do it generically from a string to any type (I need something generic that will work with templates, can't just use specializations for each type and use functions like atoi)
Edit:
Of course I've tried using the ostringstream in the opposite direction. I get this error:
error C2784: 'std::basic_istream<_Elem,_Traits> &std::operator >>(std::basic_istream<_Elem,_Traits> &&,_Elem *)' : could not deduce template argument for 'std::basic_istream<_Elem,_Traits> &&' from 'std::ostringstream'
lexical_cast uses streaming in both directions, << and >>. You could do the same:
std::stringstream sstr;
sstr << _from;
sstr >> _to;
Be sure to include sanity checks though.