std:strstream does not work
-
In Visual C++ 2012 I have written this code:
strstream& operator>>(strstream& Stream,CComponent* pCmp){
..code
}std::strstream read_file((char*)filbuf,file_size,ios_base::out);
pComp=new CComponent;
read_file>>pComp;This works perfectly. But when I run it on my newly installed Visual C++ 2019 it compiles all right, but the output is wrong. I see that std::strstream is deprecated, but it should still function. If I try to put std::stringstream instead, it will not accept the >> operator.
-
Haakon S. wrote:
it compiles all right, but the output is wrong.
You need to explain what that means.
Ok, some details. Everything seems to be identical when I check the debug data. The text file is referenced in the same way by filebuf. The first member of CComponent is specified as WORD m_nNo and the this value in the first component is 56. I put some test code on top of my function to try to find out what is going on.
std::strstream& operator>>(std::strstream& Stream,CComponent* pCmp){
char txt[4];
Stream >> txt;
.
.
.
}The watch window displays the following output from the new C++ version: - txt 0x00cfd5fc "" char[4] [0] 0 '\0' char [1] -52 'Ì' char [2] -52 'Ì' char [3] -52 'Ì' char From my older version I get the correct output: - txt 0x0055e25c "56" char[4] [0] 53'5' char [1] 54'6' char [2] 0 '\0' char [3] -52 'Ì' char It seems that the extraction operator >> simply does not work anymore. In that case, what is the best alternative for reading data from a text file. If I replace strstream with stringstream I get the message that stringstream does not have a >> operator.
-
Ok, some details. Everything seems to be identical when I check the debug data. The text file is referenced in the same way by filebuf. The first member of CComponent is specified as WORD m_nNo and the this value in the first component is 56. I put some test code on top of my function to try to find out what is going on.
std::strstream& operator>>(std::strstream& Stream,CComponent* pCmp){
char txt[4];
Stream >> txt;
.
.
.
}The watch window displays the following output from the new C++ version: - txt 0x00cfd5fc "" char[4] [0] 0 '\0' char [1] -52 'Ì' char [2] -52 'Ì' char [3] -52 'Ì' char From my older version I get the correct output: - txt 0x0055e25c "56" char[4] [0] 53'5' char [1] 54'6' char [2] 0 '\0' char [3] -52 'Ì' char It seems that the extraction operator >> simply does not work anymore. In that case, what is the best alternative for reading data from a text file. If I replace strstream with stringstream I get the message that stringstream does not have a >> operator.
-
In Visual C++ 2012 I have written this code:
strstream& operator>>(strstream& Stream,CComponent* pCmp){
..code
}std::strstream read_file((char*)filbuf,file_size,ios_base::out);
pComp=new CComponent;
read_file>>pComp;This works perfectly. But when I run it on my newly installed Visual C++ 2019 it compiles all right, but the output is wrong. I see that std::strstream is deprecated, but it should still function. If I try to put std::stringstream instead, it will not accept the >> operator.
First, stringstream is not strstream. You may need to specifically use ostringstream instead. But anyway, like Richard already stated, you should be using fstream, or ofstream.
GOTOs are a bit like wire coat hangers: they tend to breed in the darkness, such that where there once were few, eventually there are many, and the program's architecture collapses beneath them. (Fran Poretto)
-
Ok, some details. Everything seems to be identical when I check the debug data. The text file is referenced in the same way by filebuf. The first member of CComponent is specified as WORD m_nNo and the this value in the first component is 56. I put some test code on top of my function to try to find out what is going on.
std::strstream& operator>>(std::strstream& Stream,CComponent* pCmp){
char txt[4];
Stream >> txt;
.
.
.
}The watch window displays the following output from the new C++ version: - txt 0x00cfd5fc "" char[4] [0] 0 '\0' char [1] -52 'Ì' char [2] -52 'Ì' char [3] -52 'Ì' char From my older version I get the correct output: - txt 0x0055e25c "56" char[4] [0] 53'5' char [1] 54'6' char [2] 0 '\0' char [3] -52 'Ì' char It seems that the extraction operator >> simply does not work anymore. In that case, what is the best alternative for reading data from a text file. If I replace strstream with stringstream I get the message that stringstream does not have a >> operator.
Looks to me like it is the *old* version that wasn't working: your code overwrites your text variable, so why would you expect it to still hold the old value? Or maybe it is just that the VS2012 debugger didn't show these contents properly because it didn't recognize that you were writing to it.
GOTOs are a bit like wire coat hangers: they tend to breed in the darkness, such that where there once were few, eventually there are many, and the program's architecture collapses beneath them. (Fran Poretto)
-
First, stringstream is not strstream. You may need to specifically use ostringstream instead. But anyway, like Richard already stated, you should be using fstream, or ofstream.
GOTOs are a bit like wire coat hangers: they tend to breed in the darkness, such that where there once were few, eventually there are many, and the program's architecture collapses beneath them. (Fran Poretto)
Hi. Thanks for helping. ifstream accepts the >> operator and get() function.
std::ifstream read_file((char*)filbuf,file_size,ios_base::out);
.
.
pComp=new CComponent;
read_file>>pComp;This function is called:
ifstream& operator>>(ifstream& Stream,CComponent* pCmp){
Stream>>pCmp->m_nNo;
Stream.get(pCmp->m_formula,15);
.
.
}Everything works fine, except that nothing is actually read. Regards, Haakon.
-
Hi. Thanks for helping. ifstream accepts the >> operator and get() function.
std::ifstream read_file((char*)filbuf,file_size,ios_base::out);
.
.
pComp=new CComponent;
read_file>>pComp;This function is called:
ifstream& operator>>(ifstream& Stream,CComponent* pCmp){
Stream>>pCmp->m_nNo;
Stream.get(pCmp->m_formula,15);
.
.
}Everything works fine, except that nothing is actually read. Regards, Haakon.
-
Hi. Thanks for helping. ifstream accepts the >> operator and get() function.
std::ifstream read_file((char*)filbuf,file_size,ios_base::out);
.
.
pComp=new CComponent;
read_file>>pComp;This function is called:
ifstream& operator>>(ifstream& Stream,CComponent* pCmp){
Stream>>pCmp->m_nNo;
Stream.get(pCmp->m_formula,15);
.
.
}Everything works fine, except that nothing is actually read. Regards, Haakon.
Ah, yes, you're right, of course I meant ifstream, not ofstream. ;) But this statement shouldn't compile:
std::ifstream read_file((char*)filbuf,file_size,ios_base::out);
See ifstream::ifstream - C++ Reference[^] : none of the constructors match the one you're calling. Specifically no constructor does have three arguments, and none expect anything like a file size. (and why should they?) Furthermore, I wonder what that variable
filebuf
is, and why it needs to be casted tochar*
? A typecast is almost always an indication of an incorrect implementation, and in this case I think you are passing the wrong parameter! The first parameter, if you pass any, should always be the file name. What is the name of the file you want to read? You should pass it here.GOTOs are a bit like wire coat hangers: they tend to breed in the darkness, such that where there once were few, eventually there are many, and the program's architecture collapses beneath them. (Fran Poretto)
-
Ah, yes, you're right, of course I meant ifstream, not ofstream. ;) But this statement shouldn't compile:
std::ifstream read_file((char*)filbuf,file_size,ios_base::out);
See ifstream::ifstream - C++ Reference[^] : none of the constructors match the one you're calling. Specifically no constructor does have three arguments, and none expect anything like a file size. (and why should they?) Furthermore, I wonder what that variable
filebuf
is, and why it needs to be casted tochar*
? A typecast is almost always an indication of an incorrect implementation, and in this case I think you are passing the wrong parameter! The first parameter, if you pass any, should always be the file name. What is the name of the file you want to read? You should pass it here.GOTOs are a bit like wire coat hangers: they tend to breed in the darkness, such that where there once were few, eventually there are many, and the program's architecture collapses beneath them. (Fran Poretto)
Hi. It does compile. But you are right. When the read file is invoked, it does not take filbuf along with it, I can see that in the debugger. I have to figure that out. Anyway, thanks alot for your hjelp. Have a Merry Christmas. During the holiday I will try to fix the problem. If I do, I will report back. Best regards, Haakon.
-
In Visual C++ 2012 I have written this code:
strstream& operator>>(strstream& Stream,CComponent* pCmp){
..code
}std::strstream read_file((char*)filbuf,file_size,ios_base::out);
pComp=new CComponent;
read_file>>pComp;This works perfectly. But when I run it on my newly installed Visual C++ 2019 it compiles all right, but the output is wrong. I see that std::strstream is deprecated, but it should still function. If I try to put std::stringstream instead, it will not accept the >> operator.
Hi. I have managed to make things work, albeit not in the way I want to. The data to be read is in a file called datf.txt. Having this file in the same directory as the exe file and simply writing
std::ifstream read_file("datf.txt");
is working. However, I want to have the data incorporated as part of the exe file. I have therefore included the CResourceTextFile class by Hans Dietrich. In the progarm resource:
IDU_COMP_FILE TEXT "datf.txt"
and further
CResourceTextFile rf;
rf.Open(NULL, _T("IDU_COMP_FILE"));
TCHAR* filbuf=rf.GetTextBuffer();
std::ifstream read_file(filbuf);does not work anymore. It did for sstream in the older version of C++ but not for ifstream in the latest.
-
Hi. I have managed to make things work, albeit not in the way I want to. The data to be read is in a file called datf.txt. Having this file in the same directory as the exe file and simply writing
std::ifstream read_file("datf.txt");
is working. However, I want to have the data incorporated as part of the exe file. I have therefore included the CResourceTextFile class by Hans Dietrich. In the progarm resource:
IDU_COMP_FILE TEXT "datf.txt"
and further
CResourceTextFile rf;
rf.Open(NULL, _T("IDU_COMP_FILE"));
TCHAR* filbuf=rf.GetTextBuffer();
std::ifstream read_file(filbuf);does not work anymore. It did for sstream in the older version of C++ but not for ifstream in the latest.
I think your original idea in your first post... std::stringstream was probably the best way. You just needed to add a istream operator >> to handle the CComponent. Something like this:
class CComponent
{
private:
std::string something;
public:
CComponent() noexcept = default;
friend std::istream& operator >> (std::istream& in, CComponent& component);
};istream& operator >> (istream& in, CComponent& c)
{
in >> component.something;
return in;
}Which could then be used like this:
const std::string test_haakon = "Lorem ipsum dolor sit amet";
CComponent test_component;
std::stringstream test_string_stream(test_haakon.c_str());
test_string_stream >> test_component;Merry Christmas to you and your family. Best Wishes, -David Delaune UPDATE: I really hate answering these modern C++ questions because it takes a lot more effort. I shouldn't have said that it was 'probably the best way' because if you use the code above it will make a copy of the data three times. If you are able to use C++17 in your project then you will be able to avoid one of those copies by deriving a class from std::basic_streambuf as such:
class CComponent
{
private:
std::string something;
public:
CComponent() noexcept = default;
friend std::istream& operator >> (std::istream& in, CComponent& component);
};template >
class make_stream_buffer_no_copy : public std::basic_streambuf
{
public:
make_stream_buffer_no_copy(CHAR* p, size_t len)
{
basic_streambuf::setg(p, p, p + len);
basic_streambuf::setp(p, p + len);
}std::basic\_stringstream get\_stream() { return std::basic\_stringstream(basic\_streambuf::pbase(), ios\_base::in | ios\_base::out); }
};
istream& operator >> (istream& in, CComponent& c)
{
in >> c.something;
return in;
}Which you would use like this:
CHAR p2[] = "Lorem ipsum dolor sit amet";
CComponent test_component2;
make_stream_buffer_no_copy no_copy(p2,strlen(p2));
no_copy.get_stream() >> test_component2;You can avoid ALL copying if you are willing to extend your CComponent class.