Set std:cin to a string - c++

For ease of testing I wish to set Cin's input to a string I can hardcode.
For example,
std::cin("test1 \ntest2 \n");
std::string str1;
std::string str2;
getline(cin,str1);
getline(cin,str2);
std::cout << str1 << " -> " << str2 << endl;
Will read out:
test1 -> test2

The best solution IMO is to refactor your core code to a function that accepts a std::istream reference:
void work_with_input(std::istream& is) {
std::string str1;
std::string str2;
getline(is,str1);
getline(is,str2);
std::cout << str1 << " -> " << str2 << endl;
}
And call for testing like:
std::istringstream iss("test1 \ntest2 \n");
work_with_input(iss);
and for production like:
work_with_input(cin);

While I agree with #πάντα ῥεῖ that the right way to do this is by putting the code into a function and passing a parameter to it, it is also possible to do what you're asking for, using rdbuf(), something like this:
#include <iostream>
#include <sstream>
int main() {
std::istringstream in("test1 \ntest2 \n");
// the "trick": tell `cin` to use `in`'s buffer:
std::cin.rdbuf(in.rdbuf());
// Now read from there:
std::string str1;
std::string str2;
std::getline(std::cin, str1);
std::getline(std::cin, str2);
std::cout << str1 << " -> " << str2 << "\n";
}

Related

Store texts in char array then compare the contents of array

I'm trying to figure out how I can store to the char array the user input. For example user input: hello, then char array[0] = "hello"; then when he input again "hello" it will not insert to the char array since it's already on the array.
Input: hello
Output: char array[] = {"hello"};
Input: world
Output:
char array[] = {"hello","world"};
Input: hello
checks: array[i] == "hello"
Output: don't insert to char array
I need a sample program please
You might go with more C++-way using standard containers:
#include <iostream>
#include <set>
#include <string>
int main()
{
std::string buffer;
std::set<std::string> data;
std::cin >> buffer;
while (buffer != "quit")
{
if (data.find(buffer) == data.end())
{
auto res = data.insert(buffer);
if (! res.second)
std::cerr << "ERROR:: Could not insert string '" << buffer << "'." << std::endl;
}
else
std::cout << "WARNING:: String '" << buffer << "' already found." << std::endl;
std::cin >> buffer;
}
return 0;
}
Otherwise, you should do it in C-style of thinking:
store string into buffer
allocate new char array and put it into a list of arrays
traverse through the list to find if a string is already there using strcmp() function
don't forget to clean up any dynamically allocated memory at the end of your program - this would cause memory leaks
The sample code using c++ would be like this, because this is C++ not only C we can use the features C++ provide as std::string, std::vector and many other useful algorithms like std::find implemented in STL. Hope this is what you want.
#include <string> // for std::string
#include <vector> // for std::vector
#include <iostream> // for std::cout, std::cin, and std::endl;
#include <algorithm> // for std::find
int main() {
std::vector<std::string> array;
std::string line;
std::cout << "Input : ";
while(std::getline(std::cin, line)) {
if (std::find(array.begin(), array.end(), line) == array.end()) { // If we can't find the string in the array
array.push_back(line);
std::cout << "{ ";
for (std::string str: array) {
std::cout << str << ", ";
}
std::cout << "}" << std::endl;
} else {
std::cout << "Output : Don't Insert" << std::endl;
}
}
}

C++ << no operator found

string toString() {
std::stringstream punkte;
std::stringstream name;
std::cout << name << "hat" << punkte << "Punkte" << '\n'
return 0;
}
At this line of code. I'm receiving the error C++ << no operator found
I can't figure out what my mistake is. I have read and tried different solutions. But nothing works. Can somebody please help?
std::cout << name << "hat" << punkte << "Punkte" << '\n';
I also included this in my code:
#include <string> // std::string
#include <iostream> // std::cout
#include <sstream> // std::stringstream, std::stringbuf
#include <fstream>
There is no overload of operator<<() that will format a std::stringstream to a std::ostream. There error does not lie.
You are trying to call operator "<<" with a stringstream parameter. In other words:
std::cout << name;
Is equivalent to:
std::cout.operator<<(name);
And that operator<<(const std::stringstream&) function doesn't exists.
I think that what you want to do is assign each stringstream their values and then print both, isn't?
string toString()
{
std::stringstream punkte;
std::stringstream name;
name << "hat";
punkte << "Punkte";
std::cout << name.str() << punkte.str() << std::endl;
return name.str();
}
Be careful with your return value, and remember that a std::stringstream is not a std::string. If you want to retrieve the std:string in the stream, you must call the str() method.

How can I obtain the length of a const stringstream's buffer without copying or seeking?

I have a const std::stringstream and a desire to find out how many bytes there are in its underlying string buffer.
I cannot seekg to the end, tellg then seekg to the start again, because none of these operations are available constly.
I do not want to get the str().size() because str() returns a copy and this may not be a trivial amount of data.
Do I have any good options?
(The stream itself is presented to me as const, only because it is a member of another type, and I receive a const reference to an object of that type. The stream represents the contents of a "document", its encapsulating object represents a CGI response and I am trying to generate an accurate Content-Length HTTP header line from within operator<<(std::ostream&, const cgi_response&).)
I've never been very comfortable with stream buffers, but this seems to work for me:
#include <iostream>
#include <sstream>
std::stringstream::pos_type size_of_stream(const std::stringstream& ss)
{
std::streambuf* buf = ss.rdbuf();
// Get the current position so we can restore it later
std::stringstream::pos_type original = buf->pubseekoff(0, ss.cur, ss.out);
// Seek to end and get the position
std::stringstream::pos_type end = buf->pubseekoff(0, ss.end, ss.out);
// Restore the position
buf->pubseekpos(original, ss.out);
return end;
}
int main()
{
std::stringstream ss;
ss << "Hello";
ss << ' ';
ss << "World";
ss << 42;
std::cout << size_of_stream(ss) << std::endl;
// Make sure the output string is still the same
ss << "\nnew line";
std::cout << ss.str() << std::endl;
std::string str;
ss >> str;
std::cout << str << std::endl;
}
The key is that rdbuf() is const but returns a non-const buffer, which can then be used to seek.
If you want to know the remaining available input size:
#include <iostream>
#include <sstream>
std::size_t input_available(const std::stringstream& s)
{
std::streambuf* buf = s.rdbuf();
std::streampos pos = buf->pubseekoff(0, std::ios_base::cur, std::ios_base::in);
std::streampos end = buf->pubseekoff(0, std::ios_base::end, std::ios_base::in);
buf->pubseekpos(pos, std::ios_base::in);
return end - pos;
}
int main()
{
std::stringstream stream;
// Output
std::cout << input_available(stream) << std::endl; // 0
stream << "123 ";
std::cout << input_available(stream) << std::endl; // 4
stream << "567";
std::cout << input_available(stream) << std::endl; // 7
// Input
std::string s;
stream >> s;
std::cout << input_available(stream) << std::endl; // 4
stream >> s;
std::cout << input_available(stream) << std::endl; // 0
}
This is similar to #Cornstalks solution, but positions the input sequence correctly.
This should work :))
#include <iostream>
#include <sstream>
#include <boost/move/move.hpp>
int main()
{
const std::stringstream ss("hello");
std::cout << boost::move(ss).str().size();
}

C++ istream - how to read string with whitespace

in the following small program I want to read the inputString with whitespace:
#include <string>
#include <sstream>
#include <iostream>
int main( int argc , char ** argv ) {
std::string inputString(" ITEM ");
std::istringstream inputStream( inputString );
//Template:
T value;
inputStream.unsetf(std::ios::skipws);
inputStream >> value;
std::cout << "Value: [" << value << "]" << std::endl;
std::cout << "StringPos: " << inputStream.tellg() << std::endl;
std::cout << "State: " << inputStream.good() << std::endl;
}
This produces the output:
Value: []
StringPos: -1
State: 0
If I remove the the unsetf() call I instead get:
Value: [ITEM]
StringPos: 4
State: 1
I.e. as expected when whitespace is ignored. So - obviously I do something wrong with the "Don't skip whitespace" setting. Any tips?
Edit: After adding the template-like "T value" the example does not compile any longer; but it is important that the
inputStream >> value;
works. The following meta code should work as well:
if is_string(T)
value = inputString; // String values are assigned directly
else
inputStream >> value; // Other types.
Joakim
Use:
std::string line;
if(std::getline(inputStream, line)) {
// line contains one line from the input stream
} else {
// inputStream is empty, EOF or in error state
}

How to add multiple items to string in c++?

I know how to do it with cout:
cout << "string" << 'c' << 33;
But how to perform this so output is redirected to variable instead directly to standard out ?
const char* string << "string" << 'c' << 33; //doesn't work
Use std::stringstream from C++ standard library.
It works like the following:
std::stringstream ss;
ss << "string" << 'c' << 33;
std::string str = ss.str();
const char* str_ansi_c = str.c_str();
Keep in mind str still needs to be in the scope while you are using C-style str_ansi_c.
#include <sstream>
#include <iostream>
main()
{
std::stringstream ss;
ss << "string" << 'c' << 33;
std::string str = ss.str();
std::cout << str;
}