Is it possible to "prepare" input from cin? - c++

In his answer, specifically in the linked Ideone example, #Nawaz shows how you can change the buffer object of cout to write to something else. This made me think of utilizing that to prepare input from cin, by filling its streambuf:
#include <iostream>
#include <sstream>
using namespace std;
int main(){
streambuf *coutbuf = cout.rdbuf(cin.rdbuf());
cout << "this goes to the input stream" << endl;
string s;
cin >> s;
cout.rdbuf(coutbuf);
cout << "after cour.rdbuf : " << s;
return 0;
}
But this doesn't quite work as expected, or in other words, it fails. :| cin still expects user input, instead of reading from the provided streambuf. Is there a way to make this work?

#include <iostream>
#include <sstream>
int main()
{
std::stringstream s("32 7.4");
std::cin.rdbuf(s.rdbuf());
int i;
double d;
if (std::cin >> i >> d)
std::cout << i << ' ' << d << '\n';
}

Disregard that question, while further investigating it, I made it work. What I did was actually the other way around than planned; I provided cin a streambuf to read from instead of filling its own.
#include <iostream>
#include <sstream>
#include <string>
using namespace std;
int main(){
stringstream ss;
ss << "Here be prepared input for cin";
streambuf* cin_buf = cin.rdbuf(ss.rdbuf());
string s;
while(cin >> s){
cout << s << " ";
}
cin.rdbuf(cin_buf);
}
Though it would still be nice to see if it's possible to provide prepared input without having to change the cin streambuf directly, aka writing to its buffer directly instead of having it read from a different one.

Related

Why am I not getting the output from the program. Whenever I run my code it stop after taking the input? [duplicate]

This question already has answers here:
How do I pass a cin'd c style string to a function?
(2 answers)
Closed last year.
Here is my code I am expecting the output but I am not getting .It stop after taking the input
I am expecting the output if i give name Harsh
Your name is Harsh
#include <iostream>
#include <cstring>
using namespace std;
int main() {
cout << "Enter your name" << endl;
char *s;
cin >> s;
cout << "Your name is " << s;
return 0;
}
I have also tried with cin.getline(s,100);but still it is not working.
So I request to you to solve the problem and give me solution.
Your code has undefined behavior because you are not allocating any memory for s to point at. s is an uninitialized pointer.
Try this instead:
#include <iostream>
using namespace std;
int main(){
cout << "Enter your name" << endl;
char s[100];
cin >> s; // or: cin.getline(s,100);
cout << "Your name is " << s;
return 0;
}
Alternatively, you should use std::string instead, eg:
#include <iostream>
#include <string>
using namespace std;
int main(){
cout << "Enter your name" << endl;
string s;
cin >> s; // or: getline(cin,s);
cout << "Your name is " << s;
return 0;
}
s in your code is unallocated.
Since it is C++ we're talking about, you probably don't want to use pointers and memory allocation, and use std::string instead.
#include <iostream>
#include <string>
using namespace std;
int main ()
{
cout << "Enter your name" << endl;
string s; // Instead of dealing with char* allocation and memory issues.
cin >> s;
cout << "Your name is " << s;
return 0;
}
you have done it correctly but the problem with output is because of the memory allocation.
You have to allocate memory and try to avoid the concept of a pointer in that. Instead
Use string s;
or
char s[50];

Choose among more .txt

I'm working on a project and I need to select a different .txt every time based on the input.
This is what I have:
#include <iostream>
#include <cstdlib>
#include <time.h>
#include <fstream>
#include <string>
#include <stdio.h>
using namespace std;
int main()
{
string hp, att, def, vel, spec;
string answer, monster;
do
{
cout << "Which Monster?: ";
cin >> monster;
cout << endl;
ifstream selection;
selection.open(monster+".txt");
selection.close();
cout << endl << "Again? ";
cin >> answer;
}
while (answer == "y");
cout << "Hello world!" << endl;
return 0;
}
I have to get the monster string and search the .txt with the same name.
If I type "Troll" it will search for the Troll.txt
Is there a way?
This is the error I get:
F:\GdR\Campagna 1\CalcoloStats\main.cpp|22|error: no matching function for call to 'std::basic_ifstream::open(std::__cxx11::basic_string)'|
Given that monster is a std::string, this expression:
monster + ".txt"
is also a std::string.
Since C++11, you can use this as an argument to ifstream's open function just fine. However, until then, you are stuck with a limitation of ifstream which is that it can only take a C-style string.
Fortunately, you can get a C-style string from a std::string using the c_str() member function.
So, either:
selection.open((monster + "txt").c_str());
Or get a modern compiler / switch out of legacy mode.
Thanks Lightness Races in Orbit, solved with C++11 Compiler flag

c++- variables to system()

I am working on a console program for Windows, and one of my settings is an option to change the console and text color.
I am using c++, so I can do something like system("color 07");, which will make the background black and the text white.
What I want to do is to present all 16 color options, and then let the user take his pick.
(Below is a portion of my code):
int a;
int b;
cout << "Please enter your background color." << endl;
cin >> a; //the user inputs 0
cout << "Please enter your text color." << endl;
cin >> b; //the user inputs 7
How to I pass the two variables to the system() call? I googled around, but all I could find were string to system(), which I do not want.
Also, I am very well aware of how evil system() is, so if anyone has other options other than system() that will do the same thing, that would be fine. But please do not tell me how evil system() is.
Thanks in advance!!
The system command takes a single const char* parameter. Therefore you just need to build a string for the command you wish to execute.
#include <iostream>
#include <sstream>
#include <string>
int main()
{
int backgroundColor;
std::cout << "Enter background color\n";
std::cin >> backgroundColor;
int foregroundColor;
std::cout << "Enter foreground color\n";
std::cin >> foregroundColor;
std::stringstream stream;
stream << "color " << backgroundColor << foregroundColor;
std::cout << "Command to execute: '" << stream.str() << "'\n";
::system(stream.str().c_str());
return 0;
}
This could be a simpler solution using C++ constructs.
#include <iostream>
#include <string>
#include <cstdlib>
using namespace std;
int main()
{
string bgClr,fgClr;
cin >> bgClr >> fgClr;
::system((bgClr+fgClr).c_str());
return EXIT_SUCCESS;
}
char command[500] = "";
sprintf(command, "color(%d, %d)", a, b);
int result = system(command);

How to grab values before space and after a space in c++

For a project im working i want to grab text before the space and after the space.
to find the space i use the isspace method, any ideas how to get this done
Like 0x499602D2 noted in the commments, you can use std::stringstream to read from string just as you would do with any other stream (like std::cin):
#include <sstream>
#include <iostream>
#include <string>
int main()
{
int a, b;
std::stringstream ss(std::stringstream::in | std::stringstream::out);
ss << "12 14";
ss >> a;
ss >> b;
std::cout << a << std::endl;
std::cout << b << std::endl;
return 0;
}
Nice thing about this is that if you know how to work with std::cin or any other stream, you know how to work with stringstream, so you can adapt this example for you needs.

Copy float to string

I want to copy the contents of a float to a string in C++. This doesn't work.
#include <iostream>
#include <sstream>
using namespace std;
int main() {
float ans = getFloat();
stringstream ss;
string strAns;
ss >> ans;
strAns = ss.str();
cout << strAns << "\n"; // displays "0"
return 0;
}
How do I do this?
I think
ss>>ans;
should be
ss<<ans;
Edit:
As James Kanze noted, you are better off using std::ostringstream instead of std::stringstream as you are not using the bidirectional functionality of the first one. This way the compiler would also throw an error that you extracting ans from the string instead of inserting it into the string.
ss << ans; instead of ss >> ans and it will work
To work with stringstreams, you have to use the PUT TO operator( << ), with an object on the right hand side. That will convert the operator to a string(if the operator is defined for the particular type)(this operator<< is already defined for a stringstream object with float object).
Then, convert the string stream to a string.. and you will have successfully converted the object to string.
As the other answers show, it should be ss << ans, since << is used for ostreams and >> is used for istreams.
If you want just to print the float to cout, you can of course avoid the detour and just write std::cout << ans;, but I guess you want to use the string otherwise.
You should however be aware of the simplifications provided by Boost's and C++11's libraries:
#include <iostream>
#include <string> //for std::string and std::to_string
#include <boost/lexical_cast.hpp>
using namesapce std;
int main() {
float ans=getFloat();
string strAns1 = boost::lexical_cast<string>(ans); //boost way
auto strAns2 = std::to_string(ans); //C++11 way
cout << "boost: " << strAns1 << "\n"
<< "C++11: " << strAns2 << "\n";
}
You are using wrong operator:
#include <iostream>
#include <sstream>
using namespace std;
int main() {
float ans=getFloat();
stringstream ss;
string strAns;
ss << ans;
strAns=ss.str();
cout<<strAns<<"\n"; // displays "0"
return 0;
}
Just one line wrong here by the look of it. You need to stream the float into the stringsteram like this:
ss << ans;
Use
strAns = std::to_string(ans);