C++ cin Question - c++

Okay, I was writing a simple C++ function to combine cin'd strings. I'm working on Linux at the moment, so I don't have the luxury of a simple "getline(cin, input)" command. Here's the code so far:
string getLine()
{
string dummy;
string retvalue;
do
{
cin << dummy;
retvalue += dummy;
} while
return retvalue;
}
What I want to know is this: is the prompt actually asking the user for input, or is it still reading from the buffer that was left over because of a space?

There is a getline defined for strings:
std::string line;
std::getline(std::cin, line);

I'm working on Linux at the moment, so I don't have the luxury of a simple "getline(cin, input)" command.
What's Linux got to do with it? getline is standard C++, except it's spelled cin.getline(input, size[, delimiter]).
Edit: Not deleting this because it's a useful reference, but AraK's post illustrating std::getline should be preferred for people who want a std::string. istream's getline works on a char * instead.

Yes. the prompt IS actually asking the user for input, but it is expecting a word rather than a line. That is possibly why it appeared space sensitive to you.
What you want, assuming you want to read more than one line, is this.
#include <iostream>
...
std::string sLine;
while(getline(std::cin, sLine)) {
// process sLine;
}
The code had a few other issues.
cin << dummy // this should have the >> operator
The variable should probably be called "word" not "dummy"
retvalue += dummy; // you would need to add spaces between words
} while // the while test should be some test for end of line
The loop in the question is closer to a word reader.
This would do for that objective.
#include <string>
#include <iostream>
#include <list>
...
void getStandardInput(std::list<std::string> & stringList) {
std::string word;
while (true) {
cin >> word;
if (cin.eof())
return;
stringList.push_back(word);
}
}

getline() is in the <string> header
I always forget that.

Related

How to take multiple line string input in C++?

I am learning C++. I want to take multiple line string as input but I can't. I am using getline() for it but it is taking only one line input. When I press enter for writing next line it stoped taking input and print the first line.
I want to give input like the example below
Hello, I am Satyajit Roy.
I want to make a program.
I love to travel.
But it takes only the first line input.
My code:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s;
getline(cin, s);
cout << s << endl;
return 0;
}
Please help me to know how can I do that.
Thank you.
Either you write a loop to read individual lines and concatenate them to a single string, thats what this answer suggests. If you are fine with designating a specific character to signal the end of the input, you can use the getline overload that takes a delimiter as parameter:
#include <iostream>
#include <string>
int main() {
std::string s;
std::getline(std::cin,s,'x');
std::cout << s;
}
The user would have to type an x to end input, so this input
Hello, I am Satyajit Roy.
I want to make a program.
I love to travel.
x
would result in this output:
Hello, I am Satyajit Roy.
I want to make a program.
I love to travel.
Of course this won't work when the string to be entered contains x, which renders the approach rather useless.
However, instead of using a "real" character as delimiter you can use the EOF character (EOF = end of file) like this:
std::getline(std::cin, s, static_cast<char>(EOF));
Then input is terminated by whatever your terminal interprets as EOF, eg Ctrl-d in linux.
Thanks to #darcamo for enlightening me on the EOF part.
You can only read one line at a time with std::getline if you don’t provide your own delimiter. If you want to accumulate multiple lines, one at a time, you need a place to put the result. Define a second string. Read a line at a time into s with std::getline, and then append s to the result string. Like this:
std::string result;
std::string s;
while (std::getline(std::cin, s))
result += s;
You can take several lines using the code below if you know how many lines you will input.
int line=3, t;
string s, bigString;
for(int i=0 ; i<line ; i++)
{
getline(cin,s); // This is to input the sentence
bigString += s + "\n";
}
cout << bigString;
If you don't know how many lines you will input (Input from file until end of file) then you can check this.
string s;
vector<string> all;
while(getline(cin,s))
{
all.push_back(s);// This is to input the sentence
}
for(auto i:all)
{
cout << i << endl;
}

Read line in C++ till EOF

I'm writing a function that reads line by line from cin and returns when it sees ; character.
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <string.h>
using namespace std;
int read_cmd(char *cmd)
{
cout << "Please enter a string: \n";
cmd[0]='\0';
while(1){
char currentLine[10000];
currentLine[0]='\0';
cin.getline(currentLine,10000);
if (strcmp(currentLine,";")==0){
break;
}
strcat(cmd, "\n");
strcat(cmd, currentLine);
}
return 0;
}
int main(){
char cmd[1000];
while (1){
read_cmd(cmd);
cout<< cmd << endl;
}
}
I then tested it using text fed from another file via pipe.
./read_cmd < test_file
contents of test_file:
line 1
line 2
;
This outputs results just fine, however it gives me a segmentation fault at the end. Is there a way for cin to check if it's coming across an EOF and terminates?
To detect the EOF you should use something like:
while (cin.good() && !cin.eof())
{
// Read the file
}
See the documentation for cin, in particular the good() (for error checking) and eof() member functions.
In particular this example might be helpful.
I would highly suggest the use of the string object for something like this, that way you're not wasting space, as well as ensuring that you have enouch space. You can also do it without a loop.
string currentLine;
getline(cin, currentLine, ';');
Now, if you need to get just the last line with has the semi-colon, a loop is necessary, but still you can do it at little more easily.
string currentLine;
while(getline(cin, currentLine)){
if(currentLine.find(";") != string::npos){
break;
}
}
Use strings to pass things around as well. There's always the .clear() method as well that any string has for easy emptying.
string getline
string Object

How to write all words of a string into different variables?

I want to get a line of strings and write every word into it's own variable, so that I can use them for example in if clauses.
I tried:
cin >> var1;
cin >> var2;
cin >> var3;
cin >> var4;
But this only works if 4 words are entered. I need a way to count the words because I don't know if it's 1,2,3,4 or more words the user enters.
Maybe there is a way with getting the whole string:
getline(cin, string1);
And cut it into words after that.
Sorry, I searched a lot but I can't find a way.
I also tried to write the cinbuffer into a variable, but the only way I can do this is with
cin >> varx;
Which is only usefull if there is something in the cinbuffer. If not, the user gets asked for input again.
EDIT: Just found this, works for me. Thanks Anyway!
C++ cin whitespace question
You’re on the right track. You can read a line with getline() then use an istringstream to treat that line as a stream of its own. Change this for whatever type T you happen to be using.
#include <algorithm>
#include <iostream>
#include <iterator>
#include <sstream>
#include <vector>
int main(int argc, char** argv) {
using namespace std;
vector<T> values;
{
string line;
getline(cin, line);
istringstream stream(line);
// Read values into vector.
copy(istream_iterator<T>(stream), istream_iterator<T>(),
back_inserter(values));
}
cout << "Received " << values.size() << " values:\n";
// Copy values to output.
copy(values.begin(), values.end(),
ostream_iterator<T>(cout, "\n"));
return 0;
}
Writing things to different variables like this is usually the wrong answer. It seems like you want something like an array.
sounds like you use getline
http://www.cplusplus.com/reference/string/getline/
then use something like boost split to dump each item into an array
http://www.cplusplus.com/faq/sequences/strings/split/

How to read the string into a file C++

i have a little problem on writing the string into a file,
How can i write the string into the file and able to view it as ascii text?
because i am able to do that when i set the default value for str but not when i enter a str data
Thanks.
#include <iostream>
#include <fstream>
#include <cstring>
using namespace std;
int main()
{
fstream out("G://Test.txt");
if(!out) {
cout << "Cannot open output file.\n";
return 1;
}
char str[200];
cout << "Enter Customers data seperate by tab\n";
cin >> str;
cin.ignore();
out.write(str, strlen(str));
out.seekp(0 ,ios::end);
out.close();
return 0;
}
Please use std::string:
#include <string>
std::string str;
std::getline(cin, str);
cout << str;
I'm not sure what the exact problem in your case was, but >> only reads up to the first separator (which is whitespace); getline will read the entire line.
Just note that >> operator will read 1 word.
std::string word;
std::cin >> word; // reads one space seporated word.
// Ignores any initial space. Then read
// into 'word' all character upto (but not including)
// the first space character (the space is gone.
// Note. Space => White Space (' ', '\t', '\v' etc...)
You're working at the wrong level of abstraction. Also, there is no need to seekp to the end of the file before closing the file.
You want to read a string and write a string. As Pavel Minaev has said, this is directly supported via std::string and std::fstream:
#include <iostream>
#include <fstream>
#include <string>
int main()
{
std::ofstream out("G:\\Test.txt");
if(!out) {
std::cout << "Cannot open output file.\n";
return 1;
}
std::cout << "Enter Customer's data seperated by tab\n";
std::string buffer;
std::getline(std::cin, buffer);
out << buffer;
return 0;
}
If you want to write C, use C. Otherwise, take advantage of the language you're using.
I can't believe no one found the problem. The problem was that you were using strlen on a string that wasn't terminated with a null character. strlen will keep iterating until it finds a zero-byte, and an incorrect string length might be returned (or the program might crash - it's Undefined Behavior, who knows?).
The answer is to zero-initialize your string:
char str[200] = {0};
Supplying your own string as the value of str works because those in-memory strings are null-terminated.

How to read until EOF from cin in C++

I am coding a program that reads data directly from user input and was wondering how could I (without loops) read all data until EOF from standard input. I was considering using cin.get( input, '\0' ) but '\0' is not really the EOF character, that just reads until EOF or '\0', whichever comes first.
Or is using loops the only way to do it? If so, what is the best way?
The only way you can read a variable amount of data from stdin is using loops. I've always found that the std::getline() function works very well:
std::string line;
while (std::getline(std::cin, line))
{
std::cout << line << std::endl;
}
By default getline() reads until a newline. You can specify an alternative termination character, but EOF is not itself a character so you cannot simply make one call to getline().
Using loops:
#include <iostream>
using namespace std;
...
// numbers
int n;
while (cin >> n)
{
...
}
// lines
string line;
while (getline(cin, line))
{
...
}
// characters
char c;
while (cin.get(c))
{
...
}
resource
You can do it without explicit loops by using stream iterators. I'm sure that it uses some kind of loop internally.
#include <string>
#include <iostream>
#include <istream>
#include <ostream>
#include <iterator>
int main()
{
// don't skip the whitespace while reading
std::cin >> std::noskipws;
// use stream iterators to copy the stream to a string
std::istream_iterator<char> it(std::cin);
std::istream_iterator<char> end;
std::string results(it, end);
std::cout << results;
}
After researching KeithB's solution using std::istream_iterator, I discovered the std:istreambuf_iterator.
Test program to read all piped input into a string, then write it out again:
#include <iostream>
#include <iterator>
#include <string>
int main()
{
std::istreambuf_iterator<char> begin(std::cin), end;
std::string s(begin, end);
std::cout << s;
}
Probable simplest and generally efficient:
#include <iostream>
int main()
{
std::cout << std::cin.rdbuf();
}
If needed, use stream of other types like std::ostringstream as buffer instead of standard output stream here.
Sad side note: I decided to use C++ IO to be consistent with boost based code. From answers to this question I chose while (std::getline(std::cin, line)). Using g++ version 4.5.3 (-O3) in cygwin (mintty) i got 2 MB/s throughput. Microsoft Visual C++ 2010 (/O2) made it 40 MB/s for the same code.
After rewriting the IO to pure C while (fgets(buf, 100, stdin)) the throughput jumped to 90 MB/s in both tested compilers. That makes a difference for any input bigger than 10 MB...
You can use the std::istream::getline() (or preferably the version that works on std::string) function to get an entire line. Both have versions that allow you to specify the delimiter (end of line character). The default for the string version is '\n'.
while(std::cin) {
// do something
}
Wait, am I understanding you correctly? You're using cin for keyboard input, and you want to stop reading input when the user enters the EOF character? Why would the user ever type in the EOF character? Or did you mean you want to stop reading from a file at the EOF?
If you're actually trying to use cin to read an EOF character, then why not just specify the EOF as the delimiter?
// Needed headers: iostream
char buffer[256];
cin.get( buffer, '\x1A' );
If you mean to stop reading from a file at the EOF, then just use getline and once again specify the EOF as the delimiter.
// Needed headers: iostream, string, and fstream
string buffer;
ifstream fin;
fin.open("test.txt");
if(fin.is_open()) {
getline(fin,buffer,'\x1A');
fin.close();
}
One option is to a use a container, e.g.
std::vector<char> data;
and redirect all input into this collection until EOF is received, i.e.
std::copy(std::istream_iterator<char>(std::cin),
std::istream_iterator<char>(),
std::back_inserter(data));
However, the used container might need to reallocate memory too often, or you will end with a std::bad_alloc exception when your system gets out of memory. In order to solve these problems, you could reserve a fixed amount N of elements and process these amount of elements in isolation, i.e.
data.reserve(N);
while (/*some condition is met*/)
{
std::copy_n(std::istream_iterator<char>(std::cin),
N,
std::back_inserter(data));
/* process data */
data.clear();
}