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 int
s 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::string
s 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
Removing Item from Vector, While in C++11 Range 'For' Loop
How to Increase the Re-Usability of This Key-Oriented Access-Protection Pattern
Lock-Free Progress Guarantees in a Circular Buffer Queue
Copying a Polymorphic Object in C++
Py_Initialize Fails - Unable to Load the File System Codec
Deprecated Header ≪Codecvt≫ Replacement
When Were the 'And' and 'Or' Alternative Tokens Introduced in C++
How to Open an Std::Fstream (Ofstream or Ifstream) With a Unicode Filename
Using Stdlib'S Rand() from Multiple Threads
Why Will Std::Sort Crash If the Comparison Function Is Not as Operator ≪
Smart Pointers (Boost) Explained
Is Ncurses Available For Windows
Visual C++ Equivalent of Gcc'S _Attribute_ ((_Packed_))
How to Include Libraries in Visual Studio 2012
C++ Performance Challenge: Integer to Std::String Conversion