std::istream::ignore discards characters until one compares equal to delim. Is there an alternative working on strings rather then chars, i.e one that discards strings until one compares equal to the specified?
The easiest way would be to continuously extract a string until you find the right one:
std::istringstream iss;
std::string str;
std::string pattern = "find me";
while ( iss >> str && str != pattern ) ;
if (!iss) { /* Error occured */ }
This assumes that the strings are delimited with whitespace characters, of course.
Related
Given an istringstream, is it possible to "extract" its contents into a character only if the character to be extracted is non-numeric (i.e. not 0-9)?
For example, this
string foo = "+ 2 3";
istringstream iss(foo);
char c;
iss >> skipws >> c; //Do this only if c would be non-numeric
should extract '+', but if foo were "2 + 3", it shouldn't extract anything, since the first [non-whitespace] character is '2', which is numeric.
To give some context, I need this to make a recursive "normal polish notation" (i.e. prefix notation) parser.
You can use unget to put back the character if it is numeric.
string foo = "+ 2 3";
istringstream iss(foo);
char c;
iss >> skipws >> c;
if (std::isdigit(c)) iss.unget();
You can use istream::peek to check what the next character will be before extracting it. You can test the result of peek against your acceptable range, and if it matches, do the actual extraction.
BTW, if you want to skip whitespace, you'll also need to check for and handle that with peek() (by extracting and discarding whitespace characters). Even with skipws, peek() won't peek past the whitespace.
I'm trying to find a certain word in a string, but find that word alone. For example, if I had a word bank:
789540132143
93
3
5434
I only want a match to be found for the value 3, as the other values do not match exactly. I used the normal string::find function, but that found matches for all four values in the word bank because they all contain 3.
There is no whitespace surrounding the values, and I am not allowed to use Regex. I'm looking for the fastest implementation of completing this task.
If you want to count the words you should use a string to int map. Read a word from your file using >> into a string then increment the map accordingly
string word;
map<string,int> count;
ifstream input("file.txt");
while (input.good()) {
input >> word;
count[word]++;
}
using >> has the benefit that you don't have to worry about whitespace.
All depends on the definition of words: is it a string speparated from others with a whitespace ? Or are other word separators (e.g. coma, dot, semicolon, colon, parenntheses...) relevant as well ?
How to parse for words without regex:
Here an accetable approach using find() and its variant find_first_of():
string myline; // line to be parsed
string what="3"; // string to be found
string separator=" \t\n,;.:()[]"; // string separators
while (getline(cin, myline)) {
size_t nxt=0;
while ( (nxt=myline.find(what, nxt)) != string::npos) { // search occurences of what
if (nxt==0||separator.find(myline[nxt-1])!=string::npos) { // if at befgin of a word
size_t nsep=myline.find_first_of(separator,nxt+1); // check if goes to end of wordd
if ((nsep==string::npos && myline.length()-nxt==what.length()) || nsep-nxt==what.length()) {
cout << "Line: "<<myline<<endl; // bingo !!
cout << "from pos "<<nxt<<" to " << nsep << endl;
}
}
nxt++; // ready for next occurence
}
}
And here the online demo.
The principle is to check if the occurences found correspond to a word, i.e. are at the begin of a string or begin of a word (i.e. the previous char is a separator) and that it goes until the next separator (or end of line).
How to solve your real problem:
You can have the fastest word search function: if ou use it for solving your problem of counting words, as you've explained in your comment, you'll waste a lot of efforts !
The best way to achieve this would certainly be to use a map<string, int> to store/updated a counter for each string encountered in the file.
You then just have to parse each line into words (you could use find_fisrst_of() as suggested above) and use the map:
mymap[word]++;
Hi I have a string like this:
word1--tab--word2--tab--word3--tab--word4--tab--word5--tab--word6
I need to extract the third word from the string. I thought of reading character by character and getting the word after reading the second tab. But I guess it is inefficient. Can you show me a more specific way please?
std::string has the find method which returns an index. You can use
find("--", lastFoundIndex + 1)
three times to find the start index of your word, a fourth time for the end index, and then use substr.
assuming "tab" is \t;
std::istringstream str(".....");
std::string temp, word;
str >> temp >> temp >> word;
I have for example
string s = " abc edef";
I create istringstream with this string.
Is there any way to from getline get only "abc"and "edef" ? Beacouse now I get that empty string between pairs of spaces :/
Use the >> operator to get only whitespace-delimited "words".
I can read from a file 1 character at a time, but how do i make it go just one word at a time? So, read until there is a space and take that as a string.
This gets me the characters:
while (!fin.eof()){
while (fin>> f ){
F.push_back ( f );
}
If your f variable is of type std::string and F is std::vector<std::string>, then your code should do exactly what you want, leaving you with a list of "words" in the F vector. I put words in quotes because punctuation at the end of a word will be included in the input.
In other words, the >> operator automatically stops at whitespace (or eof) when the target variable type is a string.
Try this:
std::string word;
while (fin >> word)
{
F.push_back(word);
}