C++ : initialize input programmatically - c++

If we have this code snippet:
int a;
cout << "please enter a value: ";
cin >> a;
And in the terminal, the input request would look like this
please enter a value: _
How can I programatically simulate a user's typing in it.

Here's a sample how to manipulate cin's input buffer using the rdbuf() function, to retrieve fake input from a std::istringstream
#include <iostream>
#include <sstream>
#include <string>
using namespace std;
int main() {
istringstream iss("1 a 1 b 4 a 4 b 9");
cin.rdbuf(iss.rdbuf()); // This line actually sets cin's input buffer
// to the same one as used in iss (namely the
// string data that was used to initialize it)
int num = 0;
char c;
while(cin >> num >> c || !cin.eof()) {
if(cin.fail()) {
cin.clear();
string dummy;
cin >> dummy;
continue;
}
cout << num << ", " << c << endl;
}
return 0;
}
See it working
Another option (closer to what Joachim Pileborg said in his comment IMHO), is to put your reading code into a separate function e.g.
int readIntFromStream(std::istream& input) {
int result = 0;
input >> result;
return result;
}
This enables you to have different calls for testing and production, like
// Testing code
std::istringstream iss("42");
int value = readIntFromStream(iss);
// Production code
int value = readIntFromStream(std::cin);

Hey why don't you write your input in a plain text file and redirect it to cin ???
It's the simplest method.
Open Command Prompt.
Suppose your text file which will used as input is in.txt and your program is prog.exe.
Keep the text file and the program in same folder. cd to your folder. Then type:
prog.exe < in.txt
Remember, your text file will be treated exactly as it is. Shoudld't be a problem if you know cin only catches upto next whitespace character, while string input functions (e.g. cin.getline) only catch upto next newline character.
//Sample prog.cpp
#include <iostream>
using namespace std;
int main()
{
int num;
do
{
cin >> num;
cout << (num + 1) << endl;
}
while (num != 0);
return 0;
}
//Sample in.txt
2
51
77
0
//Sample output
3
52
78
1
Sorry if you are on other platform, I don't know about them.

Related

How to simulate user input to std::cin for a mcve? [duplicate]

If we have this code snippet:
int a;
cout << "please enter a value: ";
cin >> a;
And in the terminal, the input request would look like this
please enter a value: _
How can I programatically simulate a user's typing in it.
Here's a sample how to manipulate cin's input buffer using the rdbuf() function, to retrieve fake input from a std::istringstream
#include <iostream>
#include <sstream>
#include <string>
using namespace std;
int main() {
istringstream iss("1 a 1 b 4 a 4 b 9");
cin.rdbuf(iss.rdbuf()); // This line actually sets cin's input buffer
// to the same one as used in iss (namely the
// string data that was used to initialize it)
int num = 0;
char c;
while(cin >> num >> c || !cin.eof()) {
if(cin.fail()) {
cin.clear();
string dummy;
cin >> dummy;
continue;
}
cout << num << ", " << c << endl;
}
return 0;
}
See it working
Another option (closer to what Joachim Pileborg said in his comment IMHO), is to put your reading code into a separate function e.g.
int readIntFromStream(std::istream& input) {
int result = 0;
input >> result;
return result;
}
This enables you to have different calls for testing and production, like
// Testing code
std::istringstream iss("42");
int value = readIntFromStream(iss);
// Production code
int value = readIntFromStream(std::cin);
Hey why don't you write your input in a plain text file and redirect it to cin ???
It's the simplest method.
Open Command Prompt.
Suppose your text file which will used as input is in.txt and your program is prog.exe.
Keep the text file and the program in same folder. cd to your folder. Then type:
prog.exe < in.txt
Remember, your text file will be treated exactly as it is. Shoudld't be a problem if you know cin only catches upto next whitespace character, while string input functions (e.g. cin.getline) only catch upto next newline character.
//Sample prog.cpp
#include <iostream>
using namespace std;
int main()
{
int num;
do
{
cin >> num;
cout << (num + 1) << endl;
}
while (num != 0);
return 0;
}
//Sample in.txt
2
51
77
0
//Sample output
3
52
78
1
Sorry if you are on other platform, I don't know about them.

Generate an error message for an invalid number of inputs on c++ cin

I'm using the following code:
string a, b, c;
cin >> a >> b >> c;
Explained: if a user inputs e.g. "hello new world hi"
then the mapping is a='hello', b='new' and c='world'. The "hi" will be ignored - and that's the problem!
What i want is, that in case of a wrong number of arguments (more or less than 3), the user should be forced to input again (maybe by an error message).
In your code, if you type in 4 words then the last word will exist somewhere on your machine(maybe on keyboard buffer). Thus, if you use cin to type value for another variable, the last word will be assign to the variable. So to check if user has typed error or not, you can do as following:
#include<iostream>
#include<string>
#include <sstream>
using namespace std;
int main()
{
string a, b, c;
cin >> a >> b >> c;
string check="";
getline(cin, check);
if (check != "")
{
cout << "input error,try again!";
}
return 0;
}
Use getline(cin, stringName)
After the input iterate through string check the index of spaces, and then split it into whatever you want.
You even don't need to declare three string to store. You can use std::getline.
std::string a;//,b,c;
std::getline(std::cin,a); //<< b << c;
std::cout <<a;
You can read whole line with std::getline, and then separate line by spaces. For example:
#include <string>
#include <vector>
#include <iostream>
// some code...
std::string text;
std::getline(std::cin, text);
std::vector<std::string> words;
int wordCount = 0;
while (auto space = text.find_first_of(' '))
{
wordCount++;
if (wordCount > 3)
{
std::cout << "Max 3 words!" << std::endl;
break;
}
words.push_back(text.substr(0, space));
text = text.substr(space + 1);
}
This way you will have max 3 words in vector words, you can get them by calling words[0] for first, etc. At 4th read word error is printed and while loop stops.

How to simulate user input in c++? [duplicate]

If we have this code snippet:
int a;
cout << "please enter a value: ";
cin >> a;
And in the terminal, the input request would look like this
please enter a value: _
How can I programatically simulate a user's typing in it.
Here's a sample how to manipulate cin's input buffer using the rdbuf() function, to retrieve fake input from a std::istringstream
#include <iostream>
#include <sstream>
#include <string>
using namespace std;
int main() {
istringstream iss("1 a 1 b 4 a 4 b 9");
cin.rdbuf(iss.rdbuf()); // This line actually sets cin's input buffer
// to the same one as used in iss (namely the
// string data that was used to initialize it)
int num = 0;
char c;
while(cin >> num >> c || !cin.eof()) {
if(cin.fail()) {
cin.clear();
string dummy;
cin >> dummy;
continue;
}
cout << num << ", " << c << endl;
}
return 0;
}
See it working
Another option (closer to what Joachim Pileborg said in his comment IMHO), is to put your reading code into a separate function e.g.
int readIntFromStream(std::istream& input) {
int result = 0;
input >> result;
return result;
}
This enables you to have different calls for testing and production, like
// Testing code
std::istringstream iss("42");
int value = readIntFromStream(iss);
// Production code
int value = readIntFromStream(std::cin);
Hey why don't you write your input in a plain text file and redirect it to cin ???
It's the simplest method.
Open Command Prompt.
Suppose your text file which will used as input is in.txt and your program is prog.exe.
Keep the text file and the program in same folder. cd to your folder. Then type:
prog.exe < in.txt
Remember, your text file will be treated exactly as it is. Shoudld't be a problem if you know cin only catches upto next whitespace character, while string input functions (e.g. cin.getline) only catch upto next newline character.
//Sample prog.cpp
#include <iostream>
using namespace std;
int main()
{
int num;
do
{
cin >> num;
cout << (num + 1) << endl;
}
while (num != 0);
return 0;
}
//Sample in.txt
2
51
77
0
//Sample output
3
52
78
1
Sorry if you are on other platform, I don't know about them.

preload cin with a string of commands

I'm testing functions that require several console commands before they can execute. Instead of having to type those commands every single time I want to test the functionality of a particular method, I want to be able to just paste a line or two of code in my source that effectively does the same thing as typing the commands would do. I tried the following code but it seems like it just loops infinitely.
streambuf *backup;
backup = cin.rdbuf();
stringbuf s = stringbuf("1 a 1 b 4 a 4 b 9");
cin.rdbuf(&s);
cin.rdbuf(backup);
The following code works well for me
#include <iostream>
#include <sstream>
#include <string>
using namespace std;
int main() {
istringstream iss("1 a 1 b 4 a 4 b 9");
cin.rdbuf(iss.rdbuf());
int num = 0;
char c;
while(cin >> num >> c || !cin.eof()) {
if(cin.fail()) {
cin.clear();
string dummy;
cin >> dummy;
continue;
}
cout << num << ", " << c << endl;
}
return 0;
}

Ignoring a line beginning with a '#' in command prompt

I am writing a code which requires me to ignore comment lines (i.e, lines beginning with a # sign) till the end of the line. I'm using linux to code in c++. For e.g: in case of adding two numbers.
xxx#ubuntu:~ $ ./add
Enter the two numbers to be added
1 #this is the first number
2 #this is the second number
result: 3
So the comment line can be anywhere. It just has to ignore the entire line and take the next value as input.
#include <iostream>
using namespace std;
int main()
{
int a,b;
cout<< "Enter the two numbers to be added:\n";
while(cin >>a >>b)
{
if (a == '#'|| b == '#')
continue;
cout << "Result: "<<a+b;
}
return 0;
}
From what you have shown, I think this might be what you want.
int main()
{
string comment;
int nr1,nr2;
// Read the first number. It should be the first one always. No comment before number!
cin >> nr1;
// See if we can read the second number Successfully. Which means it is an integer.
if(cin >> nr2) {
}
// Otherwise clear cin and read the rest of the comment line
else {
cin.clear();
getline(cin,comment);
// Now read the second number from the second line
cin >> nr2;
}
// Read the rest of second the line.
getline(cin,comment);
cout << "result: " << nr1 + nr2 << endl;
return 0;
}
Will any number of numbers based on the value you give reqd.
Will also work if the first character in a line itself is # - will ask again for that line. Will also read another line if there is no number before the `#.
#include <iostream>
#include <sstream>
#include <ctype.h>
using namespace std;
int main ()
{
const int reqd = 2;
string sno[reqd];
int no[reqd];
int got = 0;
size_t pos;
istringstream is;
cout<< "Enter "<<reqd<<" numbers to be added:\n";
while(got < reqd)
{
getline(cin, sno[got]);
if((pos = sno[got].find('#')) && isdigit(sno[got][0]))
{
is.str(sno[got]);
is>>no[got];
++got;
}
}
int sum = 0;
for(int i = 0; i < reqd; ++i)
sum+=no[i];
cout<<"Result : "<<sum;
return 0;
}