getting cout output to a std::string - c++

I have the following cout statement. I use char arrays because I have to pass to vsnprintf to convert variable argument list and store in Msg.
Is there any way we can get cout output to C++ std::string?
char Msg[100];
char appname1[100];
char appname2[100];
char appname3[100];
// I have some logic in function which some string is assigned to Msg.
std::cout << Msg << " "<< appname1 <<":"<< appname2 << ":" << appname3 << " " << "!" << getpid() <<" " << "~" << pthread_self() << endl;

You can replace cout by a stringstream.
std::stringstream buffer;
buffer << "Text" << std::endl;
You can access the string using buffer.str().
To use stringstream you need to use the following libraries:
#include <string>
#include <iostream>
#include <sstream>

You can use std::stringstream
http://www.cplusplus.com/reference/iostream/stringstream/

If you can change the code then use ostringstream (or stringstream) instead of cout.
If you cannot change the code and want to "capture" what is being output you can redirect your output or pipe it.
It may then be possible for your process to read the file or get the piped information through shared memory.

#include <stdio.h>
#include <iostream>
#include <string>
#include <sstream>
// This way we won't have to say std::ostringstream or std::cout or std::string...
using namespace std;
/** Simulates system specific method getpid()... */
int faux_getpid(){
return 1234;
}
/** Simulates system specific method pthread_self()... */
int faux_pthread_self(){
return 1111;
}
int main(int argc, char** argv){
// Create a char[] array of 100 characters...
// this is the old-fashioned "C" way of storing a "string"
// of characters..
char Msg[100];
// Try using C++-style std::string rather than char[],
// which can be overrun, leading to
// a segmentation fault.
string s_appname1;
// Create old-fashioned char[] array of 100 characters...
char appname2[100];
// Create old-fashioned char[] array of 100 characters...
char appname3[100];
// Old-fashioned "C" way of copying "Hello" into Msg[] char buffer...
strcpy(Msg, "Hello");
// C++ way of setting std::string s_appname equal to "Moe"...
s_appname1 = "Moe";
// Old-fashioned "C" way of copying "Larry" into appname2[] char buffer...
strcpy(appname2, "Larry");
// Old-fashioned "C" way of copying "Shemp" into appname3[] char buffer...
strcpy(appname3, "Shemp");
// Declare le_msg to be a std::ostringstream...
// this allows you to use the C++ "put-to" operator <<
// but it will "put-to" the string-stream rather than
// to the terminal or to a file...
ostringstream le_msg;
// Use put-to operator << to "write" Msg, s_appname1, s_appname2, etc...
// to the ostringstream...not to the terminal...
le_msg << Msg << " "<< s_appname1 <<":"<< appname2 << ":" << appname3 << " " << "!" << faux_getpid() <<" " << "~" << faux_pthread_self();
// Print the contents of le_msg to the terminal -- std::cout --
// using the put-to operator << and using le_msg.str(),
// which returns a std::string.
cout << "ONE: le_msg = \"" << le_msg.str() << "\"..." << endl;
// Change contents of appname3 char[] buffer to "Curly"...
strcpy(appname3, "Curly");
// Clear the contents of std::ostringstream le_msg
// -- by setting it equal to "" -- so you can re-use it.
le_msg.str("");
// Use put-to operator << to "write" Msg, s_appname1, s_appname2, etc...
// to the newly cleared ostringstream...not to the terminal...
// but this time appname3 has been set equal to "Curly"...
le_msg << Msg << " "<< s_appname1 <<":"<< appname2 << ":" << appname3 << " " << "!" << faux_getpid() <<" " << "~" << faux_pthread_self();
// Print the new contents of le_msg to the terminal using the
// put-to operator << and using le_msg.str(),
// which returns a std::string.
cout << "TWO: le_msg = \"" << le_msg.str() << "\"..." << endl;
// This time, rather than using put-to operator << to "write"
// to std::ostringstream le_msg, we'll explicitly set it equal
// to "That's all Folks!"
le_msg.str("That's all Folks!");
// Print the new contents of le_msg "That's all Folks!" to
// the terminal via le_msg.str()
cout << "THREE: le_msg = \"" << le_msg.str() << "\"..." << endl;
// Exit main() with system exit value of zero (0), indicating
// success...
return 0;
}/* main() */
OUTPUT:
ONE: le_msg = "Hello Moe:Larry:Shemp !1234 ~1111"...
TWO: le_msg = "Hello Moe:Larry:Curly !1234 ~1111"...
THREE: le_msg = "That's all, folks!"...

Related

stringstream::seekp not functioning on Visual Studio 2015

I want to read a chunk of data from file into stringstream, which later will be used to parse the data (using getline, >>, etc). After reading the bytes, I set the buffer of the stringstream, but I cant make it to set the p pointer.
I tested the code on some online services, such as onlinegdb.com and cppreference.com and it works. However, on microsoft, I get an error - the pointers get out of order.
Here's the code, I replaced the file-read with a char array.
#include <sstream>
#include <iostream>
int main()
{
char* a = new char [30];
for (int i=0;i<30;i++)
a[i]='-';
std::stringstream os;
std::cout << "g " << os.tellg() << " p " << os.tellp() << std::endl;
os.rdbuf()->pubsetbuf(a,30);
os.seekp(7);
std::cout << "g " << os.tellg() << " p " << os.tellp() << std::endl;
}
the output I get when it works
g 0 p 0
g 0 p 7
the output I get on visual studio 2015
g 0 p 0
g -1 p -1
any ides?
thanks
std::sstream::setbuf may do nothing:
If s is a null pointer and n is zero, this function has no effect.
Otherwise, the effect is implementation-defined: some implementations do nothing, while some implementations clear the std::string member currently used as the buffer and begin using the user-supplied character array of size n, whose first element is pointed to by s, as the buffer and the input/output character sequence.
You are better off using the std::stringstream constructor to set the data or call str():
#include <sstream>
#include <iostream>
int main()
{
std::string str( 30, '-' );
std::stringstream os;
std::cout << "g " << os.tellg() << " p " << os.tellp() << std::endl;
os.str( str );
os.seekp(7);
std::cout << "g " << os.tellg() << " p " << os.tellp() << std::endl;
}

Print to file and console c++

I am trying to logg my events so i thought of using ostringstream to save the output and then send it to a function where i print the output on screen and on file fstream fileOut. It wont work, it just gives me random numbers and seem not to output all new outputs on the same file but just creates a new file everytime and deletes what was on it before. How do i do this?
where the print happens:
void Event::output(ostringstream* info) {
std::cout << info << std::endl;
fileOut << info << std::endl;
}
where the output happens:
ostringstream o;
if (time < SIM_TIME) {
if (status->tryAssemble(train)) {
Time ct;
ct.fromMinutes(time);
o << ct << " Train [" << train->getTrainNumber() << "] ";
Time t(0, DELAY_TIME);
o << "(ASSEMBLED) from " << train->getStart() << " " << train->getScheduledStartTime() <<
" (" << train->getStartTime() << ") to " << train->getDest() << " " << train->getScheduledDestTime() <<
" (" << train->getDestTime() << ") delay (" << train->getDelay() << ") speed=" << train->getScheduledSpeed() <<
" km/h is now assembled, arriving at the plateform at " << train->getStartTime() - t << endl << endl;
fileOut.open("testfile.txt", std::ios::out);
if (!fileOut.is_open())
exit(1); //could not open file
output(&o);
train->setStatus(ASSEMBLED);
time += ASSEMBLE_TIME;
Event *event = new ReadyEvent(simulation, status, time, train);
simulation->addEvent(event);
It wont work, it just gives me random numbers
You are passing the ostringstream to your function by pointer. There is no operator<< that takes an ostringstream* pointer as input and prints its string content. But there is an operator<< that takes a void* as input and prints the memory address that the pointer is pointing at. That is the "random numbers" you are seeing. ANY type of pointer can be assigned to a void* pointer.
You need to dereference the ostringstream* pointer to access the actual ostringstream object. Even so, there is still no operator<< that takes an ostringstream as input. However, ostringstream has a str() method that returns a std::string, and there is an operator<< for printing a std::string:
void Event::output(ostringstream* info) {
std::string s = info->str();
std::cout << s << std::endl;
fileOut << s << std::endl;
}
That being said, you should pass the ostringstream by const reference instead of by pointer, since the function does not allow a null ostringstream to be passed in, and it does not modify the ostringstream in any way:
void Event::output(const ostringstream &info) {
std::string s = info.str();
std::cout << s << std::endl;
fileOut << s << std::endl;
}
...
output(o);
seem not to output all new outputs on the same file but just creates a new file everytime and deletes what was on it before.
That is because you are not opening the file with either the app or ate flag 1, so it creates a new file each time, discarding the contents of any existing file. If you want to append to an existing file instead, you need to either:
use the ate flag to "seek to the end of stream immediately after open":
fileOut.open("testfile.txt", std::ios::out | std::ios::ate);
use the app flag to "seek to the end of stream before each write":
fileOut.open("testfile.txt", std::ios::out | std::ios::app);
1: if fileOut is a std::ofstream, you do not need to specify std::ios::out explicitly.

Why does std / boost::format cause this c_str() behaviour?

I'm using boost::format (not std:: as I'm using c++98) to format a string that I'm passing to a system() call.
When getting the c_str() of the string created by format, it seems to terminate halfway along the string. The same sting created with the literal value does not have the same problem. What's going on here?
Using Boost 1.46.1 according to BOOST_VERSION.
#include <boost/format.hpp>
#include <iostream>
#include <string>
int main(int argc, char** argv)
{
const std::string my_str = "echo '/%1%/ some other stuff'";
boost::format fmtr(my_str);
fmtr % "sleep 3"; // should read: echo '/sleep 3/ some other stuff'
std::cout << "1: " << fmtr.str() << "\n"; // 1. echo '/sleep 3/ some other stuff' (OK)
std::cout << "2: " << fmtr.str().c_str() << "\n"; // 2. echo '/sleep 3 (BAD)
// Try the c_str of a string not created through boost::format
const std::string finished = "echo '/sleep 3/ some other stuff'";
std::cout << "3: " << finished.c_str() << "\n"; // 3. echo '/sleep 3/ some other stuff' (OK)
// Try copying the string from format to see if that makes any difference (it doesn't)
std::string copy = fmtr.str();
std::cout << "4: " << copy.c_str() << "\n"; // 4. echo '/sleep 3 (BAD)
return 0;
}
Passing the c_str() to my system() call is resulting in the error:
sh -c: line 0: unexpected EOF while looking for matching `''
Presumably because it is finishing halfway along the string as well.
With proper includes your program works fine: ideone
#include <boost/format.hpp>
#include <iostream>
#include <string>
int main()
{
const std::string my_str = "echo '/%1%/ some other stuff'";
boost::format fmtr(my_str);
fmtr % "sleep 3"; // should read: echo '/sleep 3/ some other stuff'
std::cout << "1: " << fmtr.str() << "\n"; // 1. echo '/sleep 3/ some other stuff' (OK)
std::cout << "2: " << fmtr.str().c_str() << "\n"; // 2. echo '/sleep 3 (BAD)
// Try the c_str of a string not created through boost::format
const std::string finished = "echo '/sleep 3/ some other stuff'";
std::cout << "3: " << finished.c_str() << "\n"; // 3. echo '/sleep 3/ some other stuff' (OK)
// Try copying the string from format to see if that makes any difference (it doesn't)
std::string copy = fmtr.str();
std::cout << "4: " << copy.c_str() << "\n"; // 4. echo '/sleep 3 (BAD)
}
You should fix includes and return type of main and try again. If wrong behavior persist most probably you have broken version of c++ and/or boost library.

Update: program shows adress of fstream instead of the text file

I am about to write a program which asks the user if they want to "search or convert" a file, if they choose convert, they need to provide the location of the file.
I do not know why the program shows the address of the file instead of opening it.
Here is my first approach:
#include <fstream>
#include <fstream>
#include <iostream>
#include <string>
using namespace std;
int main()
{
char dateiname[64], kommando[64];
ifstream iStream;
cout << "Choose an action: " << endl <<
" s - search " << endl <<
" c - convert" << endl <<
" * - end program" << endl;
cin.getline(kommando,64,'\n');
switch(kommando[0])
{
case 'c':
cout << "Enter a text file: " << endl;
cin.getline(dateiname,64,'\n');
iStream.open("C://users//silita//desktop//schwarz.txt");
case 's': break;
case '*': return 0;
default:
cout << "Invalid command: " << kommando << endl;
}
if (!iStream)
{
cout << "The file " << dateiname << " does not exist." << endl;
}
string s;
while (getline(iStream, s)) {
while(s.find("TIT", 0) < s.length())
s.replace(s.find("TIT", 0), s.length() - s.find("TIT", 3),"*245$a");
cout << iStream << endl;
}
iStream.close();
}
At first you can't compare c-strings using ==. You must use strcmp(const char*, const char*). More info about it you can find there: http://www.cplusplus.com/reference/cstring/strcmp/
For example: if (i == "Konvertieren") must become if(!strcmp(i,"Konvertieren"))
As mentioned in Lassie's answer, you can't compare strings in this way using c or c++; just to flesh it out, however, I'll explain why.
char MyCharArr[] = "My Character Array"
// MyCharArr is now a pointer to MyCharArr[0],
// meaning it's a memory address, which will vary per run
// but we'll assume to be 0x00325dafa
if( MyCharArr == "My Character Array" ) {
cout << "This will never be run" << endl;
}
Here the if compares a pointer (MyCharArr) which will be a memory address, ie an integer, to a character array literal. Obviously 0x00325dafa != "My Character Array".
Using cstrings (character arrays), you need to use the strcmp() function which you will find in the cstring library, which will give you a number telling you "how different" the strings are, essentially giving the difference a numerical value. In this instance we are only interested in no difference, which is 0, so what we need is this:
#include <cstring>
using namespace std;
char MyCharArr[] = "My Character Array"
if( strcmp(MyCharArr,"My Character Array")==0 ) {
// If there is 0 difference between the two strings...
cout << "This will now be run!" << endl;
}
While you are not doing so in your question, If we were using c++ strings rather than character arrays, we would use the compare() method to similar affect:
#include <string>
using namespace std;
string MyString = "My C++ String"
if( MyString.compare("My C++ String")==0 ) {
// If there is 0 difference between the two strings...
cout << "This will now be run!" << endl;
}

Where do we really need to use wide character stream wcout?

I can't get the point of using std::wcout. As far as I've understood the wide stream object corresponds to a C wide-oriented stream (ISO C 7.19.2/5). When do we really need to use it in practice. I'm pretty sure it doesn't suit to output a character from an implementation's wide character set N3797::3.9.1/5 [basic.fundamental], because
#include <iostream>
#include <locale>
int main()
{
std::locale loc = std::locale ("en_US.UTF-8");
std::wcout.imbue(loc);
std::cout << "ي" << std::endl; // OK!
std::wcout << "ي" << std::endl; // Empty string
std::wcout << "L specifier = " << L"ي" << std::endl; // J
std::wcout << "u specifier = " << u"ي" << std::endl; // 0x400,eac
std::wcout << "u8 specifier = " << u8"ي" << std::endl; // empty string
}
DEMO
We can see that wcout's operator<< didn't print these characters correct, meanwhile cout's operator<< does it well. I've also chech wcout on any other charater like
'л', 'ਚੰ', 'ਗਾ', 'კ', 'ა', 'რ', 'გ', 'ი' and so on and so forth, but it prints well only a Latinic characters or a numbers.