I have the following string "0 1 2 3 4 "(There is a space at the end of the string). Which i would like to split and add to a vector of string. When i use a loop and a stringstream, the program loops itself into a infinity loop with the last number 4. It does not want to stop.
How can I split the following and add to a vector of strings at the same time.
Please advcie.
stringstream ss(currentLine);
for(int i=0;i<strlen(currentLine.c_str());i++){
ss>>strCode;
strLevel.push_back(strCode);
}
std::ifstream infile(filename.c_str());
std::string line;
if (infile.is_open())
{
std::cout << "Well done! File opened successfully." << std::endl;
while (std::getline(infile, line))
{
std::istringstream iss(line);
std::vector<std::string> tokens { std::istream_iterator<std::string>(iss), std::istream_iterator<std::string>() };
for (auto const &token : tokens)
if (!token.compare("your_value"))
// Do something....
}
}
First of all, we read a line just by using std::istringstream iss(line), then we split words according to the whitespaces and store them inside the tokens vector.
Update: thanks to Nawaz for improvement suggestions (see comments).
stringstream ss(currentLine);
while ( ss >> strCode )
strLevel.push_back(strCode);
That should be enough.
Related
I have an input getline:
man,meal,moon;fat,food,feel;cat,coat,cook;love,leg,lunch
And I want to split this into an array when it sees a ;, it can store all values before the ; in an array.
For example:
array[0]=man,meal,moon
array[1]=fat,food,feel
And so on...
How can I do it? I tried many times but I failed!😒
Can anyone help?
Thanks in advance.
You can use std::stringstream and std::getline.
I also suggest that you use std::vector as it's resizeable.
In the example below, we get input line and store it into a std::string, then we create a std::stringstream to hold that data. And you can use std::getline with ; as delimiter to store the string data between the semicolon into the variable word as seen below, each "word" which is pushed back into a vector:
int main()
{
string line;
string word;
getline(cin, line);
stringstream ss(line);
vector<string> vec;
while (getline(ss, word, ';')) {
vec.emplace_back(word);
}
for (auto i : vec) // Use regular for loop if you can't use c++11/14
cout << i << '\n';
Alternatively, if you can't use std::vector:
string arr[256];
int count = 0;
while (getline(ss, word, ';') && count < 256) {
arr[count++] = word;
}
Live demo
Outputs:
man,meal,moon
fat,food,feel
cat,coat,cook
love,leg,lunch
I don't want to give you some code because you must be new at C++ and you have to learn by yourself but I can give an hint: use substring to store it into a vector of string.
I'm having problem to split the string with space as a delim. I have tried 2 of the proposed solution as in here:
Split a string in C++?
(using copy + istringstream and split method)
However, no matter what I did, the vector only get the first word (not the rest). When I use the split method, it's working with anything else (dot, comma, semi colon...) but not space.
Here is my current code, can you tell me what I get wrong? Or how I should try to approach the fix?
int main()
{
std::vector<std::string> textVector;
std::string textString;
std::cout << "Input command : ";
std::cin >> textString;
std::istringstream iss(textString);
std::copy(std::istream_iterator<std::string>(iss), std::istream_iterator<std::string>(), std::back_inserter(textVector));
for (int i = 0 ; i < textVector.size(); i++) {
std::cout << textVector[i];
}
return 0;
}
The runnable code: http://cpp.sh/8nzq
Reason is simple, std::cin >> textString only reads until first whitespace. So textString only contains the first word.
To read entire line, you should instead use: std::getline(std::cin, textString);
I have a csv that I'd like to tokenize line by line with StringStream. The key is that I know apriori what the columns would look like. For example, say I know the file looks like the following
StrHeader,IntHeader
abc,123
xyz,456
I know ahead of time it is a string column, followed by an int column.
Common approach is to read the file line by line
std::string line;
stringstream lineStream;
while (getline(infile, line)) // read line by line
{
cout << "line " << line << endl;
lineStream << line;
string token;
while(getline(lineStream, token, ',')) // push into vector? this is not ideal
{
}
I know I can have 2 loops, and have inner loop tokenizes the string based on commas. Lots of sample code on stackoverflow would store the result into a vector<string>.
I don't want to do create a new vector every line. Since I know apriori what columns the file would have, can I somehow read directly into a string and int variable? Like this
std::string line;
stringstream lineStream;
while (getline(infile, line)) // read line by line
{
cout << "line " << line << endl;
lineStream << line; // DOESNT WORK - tell lineStream we have comma delimited string
string strValue;
int intValue;
lineStream >> strValue >> intValue; // SO MUCH CLEANER
// call foo(strValue, intValue);
}
The problem above is this line
lineStream << line; // DOESNT WORK - tell lineStream we have comma delimited string
From what I could tell, the above code works if the input line is space delimited, not comma delimited.
I have no control over the input. So, simply replacing the "spaces" with "commas" in the original string is not an ideal solution since I don't know if the input already has spaces.
Any ideas? thanks
You could try to only read to the delimiter with std::getline() and then put that in a string stream for conversion.
while (!infile.eof()){
std::getline(infile, strValue, ',');
std::getline(infile, line);
strstr.str(line);
strstr.clear();
int intValue;
strstr >> intValue;
foo(strValue, intValue);
}
This question already has answers here:
taking input of a string word by word
(3 answers)
Closed 8 years ago.
Is there some way to read consecutive words separated by spaces as strings until end of line is found in C++? To be precise, I'm working on an algorithmic problem and the input goes like:
some_word1 some_word2 some_word3 (...) some_wordn
other_data
And the trick is I don't know how many words will there be in the first line, just that I should read them as separate words for further processing. I know I could use getline(), but after that I'd have to work char-by-char to write each word in a new string when space occurs. Not that it's a lot of work, I'm just curious if there's a better way of doing this.
Why would you have to work character by character after using getline?
The usual way of parsing line oriented input is to read line by line,
using getline, and then use an std::istringstream to parse the line
(assuming that is the most appropriate parsing tool, as it is in your
case). So to read the file:
std::string line;
while ( std::getline( input, line ) ) {
std::istringstream parse( line );
// ...
}
You could use sstream and combine it with getline(), which is something you already know.
#include <iostream>
#include <sstream>
int main()
{
std::string fl;
std::getline(std::cin, fl); // get first line
std::istringstream iss(fl);
std::string word;
while(iss >> word) {
std::cout << "|" << word << "|\n";
}
// now parse the other lines
while (std::getline(std::cin, fl)) {
std::cout << fl << "\n";
}
}
Output:
a b
|a|
|b|
a
a
g
g
t
t
You can see that the spaces are not saved.
Here you can see relevant answers:
Split a string in C++
Taking input of a string word by word
I would suggest to read the complete line as a string and split the string into a vector of strings.
Splitting a string can be found from this question Split a string in C++?
string linestr;
cin>>linestr;
string buf; // Have a buffer string
stringstream ss(linestr); // Insert the string into a stream
vector<string> tokens; // Create vector to hold our words
while (ss >> buf)
tokens.push_back(buf);
I know about getline() but it would be nice if cin could return \n when encountered.
Any way for achieving this (or similar)?
edit (example):
string s;
while(cin>>s){
if(s == "\n")
cout<<"newline! ";
else
cout<<s<<" ";
}
input file txt:
hola, em dic pere
caram, jo també .
the end result shoud be like:
hola, em dic pere newline! caram, jo també .
If you are reading individual lines, you know that there is a newline after each read line. Well, except for the last line in the file which doesn't have to be delimited by a newline character for the read to be successful but you can detect if there is newline by checking eof(): if std::getline() was successful but eof() is set, the last line didn't contain a newline. Obviously, this requires the use of the std::string version of std::getline():
for (std::string line; std::getline(in, line); )
{
std::cout << line << (in.eof()? "": "\n");
}
This should write the stream to std::cout as it was read.
The question asked for the data to be output but with newlines converted to say "newline!". You can achieve this with:
for (std::string line; std::getline(in, line); )
{
std::cout << line << (in.eof()? "": "newline! ");
}
If you don't care about the stream being split into line but actually just want to get the entire file (including all newlines), you can just read the stream into a std::string:
std::string file((std::istreambuf_iterator<char>(in)),
std::istreambuf_iterator<char>());
Note, however, that this exact approach is probably fairly slow (although I know that it can be made fast). If you know that the file doesn't contain a certain character, you can also use std::getline() to read the entire file into a std::string:
std::getline(in, file, 0);
The above code assumes that your file doesn't contain any null characters.
A modification of #Dietmar's answer should do the trick:
for (std::string line; std::getline(in, line); )
{
std::istringstream iss(line);
for (std::string word; iss >> word; ) { std::cout << word << " "; }
if (in.eof()) { std::cout << "newline! "; }
}
Just for the record, I ended up using this (I wanted to post it 11h ago)
string s0, s1;
while(getline(cin,s0)){
istringstream is(s0);
while(is>>s1){
cout<<s1<<" ";
}
cout<<"newline! ";
}