How to Read a Complete Line from the User Using Cin

Reading a full line of input

is there a way like readLines till CTRL+Z is pressed or something ??

Yes, precisely like this, using the free std::getline function (not the istream method of the same name!):

string line;

while (getline(cin, line)) {
// do something with the line
}

This will read lines (including whitespace, but without ending newline) from the input until either the end of input is reached or cin signals an error.

C++ reading input from cin until the whole line has been read

Now that you clarified your question it's way clearer. And @TeoZec answer should be right. I just wanna note two things that seem buggy in your above code:

else if (c == '-')
{
num.push(a+b);
count--;
}

here you probably wanted a-b instead.

if (count>1)
{
b = num.top();
a = num.top();
num.pop();
num.pop();

b and a will be the same number here, you should call pop() before getting the second number, like:

if (count>1)
{
b = num.top();
num.pop();
a = num.top();
num.pop();

Reading lines from input

You could use std::from_chars (and reserve() the approximate amount of lines you have in the file, if you store the values in a vector for example). I also suggest adding support for reading directly from the file. Reading from a file opened by the program is (at least for me) faster than reading from std::cin (even with sync_with_stdio(false)).

Example:

#include <algorithm> // std::for_each
#include <cctype> // std::isspace
#include <charconv> // std::from_chars
#include <cstdio> // std::perror
#include <fstream>
#include <iostream>
#include <iterator> // std::istream_iterator
#include <limits> // std::numeric_limits

struct foo {
int a[3];
std::string s;
};

std::istream& operator>>(std::istream& is, foo& f) {
if(std::getline(is, f.s)) {
std::from_chars_result fcr{f.s.data(), {}};
const char* end = f.s.data() + f.s.size();

// extract the numbers
for(unsigned i = 0; i < 3 && fcr.ptr < end; ++i) {
fcr = std::from_chars(fcr.ptr, end, f.a[i]);
if(fcr.ec != std::errc{}) {
is.setstate(std::ios::failbit);
return is;
}
// find next non-whitespace
do ++fcr.ptr;
while(fcr.ptr < end &&
std::isspace(static_cast<unsigned char>(*fcr.ptr)));
}

// extract the string
if(++fcr.ptr < end)
f.s = std::string(fcr.ptr, end - 1);
else
is.setstate(std::ios::failbit);
}
return is;
}

std::ostream& operator<<(std::ostream& os, const foo& f) {
for(int i = 0; i < 3; ++i) {
os << f.a[i] << ',';
}
return os << '\'' << f.s << "'\n";
}

int main(int argc, char* argv[]) {
std::ifstream ifs;
if(argc >= 2) {
ifs.open(argv[1]); // if a filename is given as argument
if(!ifs) {
std::perror(argv[1]);
return 1;
}
} else {
std::ios_base::sync_with_stdio(false);
std::cin.tie(nullptr);
}

std::istream& is = argc >= 2 ? ifs : std::cin;

// ignore the first line - it's of no use in this demo
is.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

// read all `foo`s from the stream
std::uintmax_t co = 0;
std::for_each(std::istream_iterator<foo>(is), std::istream_iterator<foo>(),
[&co](const foo& f) {
// Process each foo here
// Just counting them for demo purposes:
++co;
});
std::cout << co << '\n';
}

My test runs on a file with 1'000'000'000 lines with content looking like below:

2,2,2,'abcd'
2, 2,2,'abcd'
2, 2, 2,'abcd'
2, 2, 2, 'abcd'

Unix time wc datafile

1000000000  2500000000 14500000000 datafile

real 1m53.440s
user 1m48.001s
sys 0m3.215s

time ./my_from_chars_prog datafile

1000000000

real 1m43.471s
user 1m28.247s
sys 0m5.622s

From this comparison I think one can see that my_from_chars_prog is able to successfully parse all entries pretty fast. It was consistently faster at doing so than wc - a standard unix tool whos only purpose is to count lines, words and characters.

C++: Reading lines of integers from cin

First use getline to grab an entire line, then you can use a istringstream to create a stream of ints just for that line.

At that point it's just a matter of creating each subvector of ints using the vector constructor that takes two iterators. An istream_iterator<int> on your istringstream gets this done:

std::vector<std::vector<int>> nums;
std::string line;
while (std::getline(std::cin, line)) {
std::istringstream ss(line);
nums.emplace_back(std::istream_iterator<int>{ss}, std::istream_iterator<int>{});
}

How do I read from cin until it is empty?

If the file contains two line feeds in a row this would not work. You can use cin.eof() to check when you’ve reached the end of the file. If it returns 1 then you’ve attempted to read beyond the end of the file.

Reading a whole line from file in c++

Edit: In response to feedback on my question, I have edited it to use the more appropriate std::getline instead of std::istream::getline. Both of these would suffice, but std::getline is better suited for std::strings and you don't have to worry about specifying the string size.

Use std::getline() from <string>.

There is a good reference and example here: http://www.cplusplus.com/reference/string/getline/.

You'll also need to be careful combining the extraction (>>) operator and getline. The top answer to this question (cin>> not work with getline()) explains briefly why they shouldn't be used together. In short, a call to cin >> (or whatever input stream you are using) leaves a newline in the stream, which is then picked up by getline, giving you an empty string. If you really want to use them together, you have to call std::istream::ignore in between the two calls.



Related Topics



Leave a reply



Submit