std::string token, line("This is a sentence.");
std::istringstream iss(line);
getline(iss, token, ' ');
std::cout << token[0] << "\n";
This is printing individual letters. How do I get the complete words?
Updated to add:
I need to access them as words for doing something like this...
if (word[0] == "something")
do_this();
else
do_that();
std::string token, line("This is a sentence.");
std::istringstream iss(line);
getline(iss, token, ' ');
std::cout << token << "\n";
To store all the tokens:
std::vector<std::string> tokens;
while (getline(iss, token, ' '))
tokens.push_back(token);
or just:
std::vector<std::string> tokens;
while (iss >> token)
tokens.push_back(token);
Now tokens[i] is the ith token.
You would first have to define what makes a word.
If it's whitespace, iss >> token is the default option:
std::string line("This is a sentence.");
std::istringstream iss(line);
std::vector<std::string> words.
std::string token;
while(iss >> token)
words.push_back(token);
This should find
This
is
a
sentence.
as words.
If it's anything more complicated than whitespace, you will have to write your own lexer.
Your token variable is a String, not an array of strings. By using the [0], you're asking for the first character of token, not the String itself.
Just print token, and do the getline again.
You've defined token to be a std::string, which uses the index operator [] to return an individual character. In order to output the entire string, avoid using the index operator.
Related
I'm trying to obtain the last column of my CSV file. I tried using getline and the stringstream but it doesn't get the last column only
stringstream lineStream(line);
string bit;
while (getline(inputFile, line))
{
stringstream lineStream(line);
bit = "";
getline(lineStream, bit, ',');
getline(lineStream, bit, '\n');
getline(inputFile, line);
stringVector.push_back(bit);
}
My CSV file:
5.1,3.5,1.4,0.2,no
4.9,3.0,1.4,0.2,yes
4.7,3.2,1.3,0.2,no
4.6,3.1,1.5,0.2,yes
5.0,3.6,1.4,0.2,no
5.4,3.9,1.7,0.4,yes
Probably the simplest approach is to use std::string::rfind as follows:
while (std::getline(inputFile, line))
{
// Find position after last comma, extract the string following it and
// add to the vector. If no comma found and non-empty line, treat as
// special case and add that too.
std::string::size_type pos = line.rfind(',');
if (pos != std::string::npos)
stringVector.push_back(line.substr(pos + 1));
else if (!line.empty())
stringVector.push_back(line);
}
I'm having trouble with stringstream. So I am getting tokens from a csv file and assigning them to some variables but I am clearing stringstream sv after I read every token and after the very first token it stops working and I am not sure why. The commented line, 'stops working here', is where it stops correctly extracting. In visual studio it says sv is '0x000' even after insert operation. I even have another loop in my code that clears it once and does insertion again and that works.
int reviewid;
int userid;
int rating;
string reviewDate;
getline(reviewReader, dummyLine); // skip first line of input
while (getline(reviewReader, input)) {
stringstream ss, sv; // sv used for type conversions
// using delimeter of commas
// order of input in the file is [ movieid, moviename, pubyear]
// , first toiken is movieid, second token will be moviename
// third token will be pubyear
ss << input; // take in line of input
getline(ss, token, ','); // first token
sv << token; // convert toiken to int
sv >> reviewid;
getline(ss, token, ','); //
sv.str("");
sv << token; // STOPS WORKING HERE
sv >> movieid;
sv.str(""); // clear buffer
getline(ss, token, ',');
sv << token;
sv >> userid;
sv.str("");
getline(ss, token, ',');
sv << token;
sv >> rating;
sv.str("");
getline(ss, token, ',');
sv << token;
sv >> reviewDate;
sv.str("");
Review r = Review(reviewid, movieid, userid, rating, reviewDate); // make review object
reviews.push_back(r); // add it to vector of reviews
}
str("") does not change the state of your stream.
i.e. if the stream was in eof state before str("") it will still be in the same state after str("").
In order to clear the state please use clear();
sv.str("");
sv.clear();
I am reading data from a file and putting it into string tokens like so:
std::vector<Mytype> mytypes;
std::ifstream file("file.csv");
std::string line;
while (std::getline(file, line)){
std::stringstream lineSs(line);
std::vector<std::string> tokens;
std::string token;
while (std::getline(lineSs, token, ',')){
tokens.push_back(token);
}
Mytype mytype(tokens[0], tokens[1], tokens[2], tokens[3]);
mytypes.push_back(mytype);
}
Obviously a pretty standard way of doing this. However the data has no NULL values, instead it will just be empty at that point. What I mean is the data may look something like this:
id0,1,2,3
id1,,2,
id2,,,3
The case of the middle line is causing me problems, because nothing is getting pushed back into my tokens vector after the "2", though there should be an empty string. Then I get some out_of_range problems when I try to create an instance of Mytype.
Until now I have been checking to see if the last char of each line is a comma, and if so, appending a space to the end of the line. But I was wondering if there was a better way to do this.
Thanks.
The difference is that line 2 has !lineSs.eof() before the last call to getline(). So you should stop the loop not if getline() returns false (note: this isn't really getline() returning false, but the stream being false when casted to bool); instead, stop it once lineSs.eof() returns true.
Here is a modification of your program that shows the idea:
int main() {
std::string line;
while (std::getline(std::cin, line)){
std::stringstream lineSs(line);
std::vector<std::string> tokens;
do {
std::string token;
std::getline(lineSs, token, ',');
tokens.push_back(token);
std::cout << "'" << token << "' " << lineSs.eof() << ' ' << lineSs.fail() << std::endl;
} while(!lineSs.eof());
std::cout << tokens.size() << std::endl;
}
}
It will show "3" on the last line for "1,2,3", and "4" for "1,2,3,".
A simple way to add a null string to the vector if the line ends with a comma is just to check for that before you create mytype. If you add
if (line.back() == ',')
tokens.push_back("");
After your inner while loop then this will add an empty string to tokens in the event that you end will a null column.
So
while (std::getline(lineSs, token, ',')){
tokens.push_back(token);
}
Becomes
while (std::getline(lineSs, token, ',')){
tokens.push_back(token);
}
if (line.back() == ',')
tokens.push_back("");
I have a string that is written as follows:
^SYSINFO:2,3,0,3,1,,3
You will notice that there is one digit missing in the line, this may not always be the case. I use sscanf to scan the line and extract the last integer.
sscanf(response_c, "^SYSINFO:%*d,%*d,%*d,%*d,%*d,,%d", &networkattach_i);
How can I compensate for the digit that is currently missing, but may be written also?
The following does NOT work:
sscanf(response_c, "^SYSINFO:%*d,%*d,%*d,%*d,%*d,%*d,%d", &networkattach_i);
You can try using getline to parse your string. An example would be,
using namespace std;
string input = "^SYSINFO:2,3,0,3,1,,3";
istringstream ss(input);
string token;
getline(ss, token, ':'); //reads till SYSINFO
while(getline(ss, token, ',')) {
cout << token << '\n';
}
I was wondering if there was a way to read all of the "words" from a line of text.
the line will look like this: R,4567890,Dwyer,Barb,CSCE 423,CSCE 486
Is there a way to use the comma as a delimiter to parse this line into an array or something?
Yes, use std::getline and stringstreams.
std::string str = "R,4567890,Dwyer,Barb,CSCE 423,CSCE 486";
std::istringstream iss(str);
std::vector<std::string> words;
while (std::getline(iss, str, ','))
words.push_back(str);
//#include sstream with angular braces in header files
std::string str = "R,4567890,Dwyer,Barb,CSCE 423,CSCE 486";
std::istringstream iss(str,istringstream:in);
vector<std::string> words;
while (std::getline(iss, str, ','))
words.push_back(str);