I am trying to take strings as input from cin
, and then push the string into a vector each time. However, my loop doesn't terminate even when I put a '\' at the end of all my input.
int main(void) {
string row;
vector<string> log;
while (cin >> row) {
if (row == "\n") {
break;
}
log.push_back(row);
}
return 0;
}
I've tried replacing the (cin >> row
) with (getline(cin,row)
), but it didn't make any difference. I've tried using stringstream, but I don't really know how it works. How do I go about resolving this?
As commented by @SidS, the whitespace is discarded. So you have to think about another strategy.
You could instead check if row
is empty. But that will only work with std::getline
:
#include <vector>
#include <string>
#include <iostream>
int main() {
std::string row;
std::vector<std::string> log;
while (std::getline(std::cin, row)) {
if (row.empty()) {
break;
}
log.push_back(row);
}
std::cout << "done\n";
}
OP, in case you want to save single words (rather than a whole line), you can use regex
to single-handedly push each of them into log
after input:
#include <vector>
#include <string>
#include <iostream>
#include <regex>
int main() {
const std::regex words_reg{ "[^\\s]+" };
std::string row;
std::vector<std::string> log;
while (std::getline(std::cin, row)) {
if (row.empty()) {
break;
}
for (auto it = std::sregex_iterator(row.begin(), row.end(), words_reg); it != std::sregex_iterator(); ++it){
log.push_back((*it)[0]);
}
}
for (unsigned i = 0u; i < log.size(); ++i) {
std::cout << "log[" << i << "] = " << log[i] << '\n';
}
}
Example run:
hello you
a b c d e f g
18939823
@_@_@ /////
log[0] = hello
log[1] = you
log[2] = a
log[3] = b
log[4] = c
log[5] = d
log[6] = e
log[7] = f
log[8] = g
log[9] = 18939823
log[10] = @_@_@
log[11] = /////
If you want to store the tokens of one line from std::cin
, separated by the standard mechanism as in the operator>>
overloads from <iostream>
(i.e., split by whitespace/newline), you can do it like this:
std::string line;
std::getline(std::cin, line);
std::stringstream ss{line};
const std::vector<std::string> tokens{std::istream_iterator<std::string>{ss},
std::istream_iterator<std::string>{}};
Note that this is not the most efficient solution, but it should work as expected: process only one line and use an existing mechanism to split this line into individual std::string
objects.
You can't read newline by using the istream& operator >>
of string. This operator ignores whitespaces and will never return the string "\n"
. Consider using getline instead.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With