C++ search for words string - c++

I want to create program which will go through sentence and if it finds a character or a word it will display it.
Think of a program that stops as soon as it find first character/word.
string test("This is sentense i would like to find ! "); //his is sentense to be searched
string look; // word/char that i want to search
cin >> look;
for (i = 0; i < test.size(); i++) //i<string size
{
unsigned searcher = test.find((look));
if (searcher != string::npos) {
cout << "found at : " << searcher;
}
}

You do not need the loop. Just do:
std::cin >> look;
std::string::size_type pos = test.find(look);
while (pos != std::string::npos)
{
// Found!
std::cout << "found at : " << pos << std::endl;
pos = test.find(look, pos + 1);
}
Here is a live example showing the result for the input string "is".

Related

My vector prints all elements but last one c++

This is making no sense to me. I do something to the code and it works only the first time. I then test it again and it goes back to not including the last element in the vector. I have no idea what I am doing wrong. Please help.
cout << "Enter a sentence: " << endl;
getline(cin, sentence);
for (auto x : sentence) // stores individual words in the vector
{
if (x == ' ')
{
myString.push_back(word);
cout << word << endl;
word = " ";
}
else
{
word = word + x;
}
}
for (auto elem : myString)
{
cout << elem << endl;
}
You are scanning the sentence one letter at a time, appending each letter to word until you encounter a space, and only then are you inserting the word into the vector. So, if the sentence does not end with a space, the last word won't be inserted into the vector.
There are a few different ways you can fix that:
check if word is not empty after the loop exits, and if not then insert it into the vector:
cout << "Enter a sentence: " << endl;
getline(cin, sentence);
for (auto x : sentence)
{
if (isspace(static_cast<unsigned char>(x))
{
if (!word.empty())
{
myString.push_back(word);
word = "";
}
}
else
{
word += x;
}
}
if (!word.empty())
{
myString.push_back(word);
}
for (const auto &elem : myString)
{
cout << elem << endl;
}
Scan for word boundaries yourself, such as with string::find_first_(not_)of():
cout << "Enter a sentence: " << endl;
getline(cin, sentence);
const char* wspace = " \f\n\r\t\v";
size_t start = 0, end;
while ((start = sentence.find_first_not_of(wspace, start)) != string::npos)
{
end = sentence.find_first_of(wspace, start + 1));
if (end == string::npos)
{
myString.push_back(sentence.substr(start));
break;
}
myString.push_back(sentence.substr(start, end-start));
start = end + 1;
}
for (const auto &elem : myString)
{
cout << elem << endl;
}
put the sentence into a std::istringstream and then use operator>> to extract complete whitespace-separate words from it. Let the standard library do all the heavy parsing for you:
cout << "Enter a sentence: " << endl;
getline(cin, sentence);
istringstream iss(sentence);
while (iss >> word)
{
myString.push_back(word);
}
for (const auto &elem : myString)
{
cout << elem << endl;
}
If there is no space after the last word, you are not adding it to your vector.

c++ reading user inputted char one by one symbol

So I have been searching, but couldn't exactly find a solution for the thing I want to do. Basically User input's a char like "asdasdasd" and I need to go thru each symbol to check if it's 'a', and need to stop the loop after it has reached the end of char. I got this far and it works, it output's the char symbols one by one, but in this case I can't stop the loop, I tried adding another char at the end and make it something specific like "." and use that to stop the loop but then I need to use char o[] which brakes the symbol by symbol thing going on there. Need help.. any input would be appreciated.
#include <iostream>
using namespace std;
int main(){
char o;
cout<<"input: "; cin>>o;
while(o!= '\0'){
cout<<o<<"\n";
cin >> o;
}
return 0;
}
When I understand your question correct you will input a string like "ahobansodfb" and search in there after a specific char? If yes, this is a little example:
#include <iostream>
using namespace std;
int main() {
string input;
char search;
int findPos = 0, countOfSearchedChars = 0;
cout << "input searched char: ";
cin >> search;
cout << "input string: ";
cin >> input;
while((findPos = input.find_first_of(search, findPos)) != string::npos){
cout << "Find searched char on pos: " << findPos << endl;
++findPos;
++countOfSearchedChars;
}
if(countOfSearchedChars == 0)
cout << "Char: " << search << " not found in: " << input << endl;
else
cout << "Char: " << search << " found: " << countOfSearchedChars << " time/s in string: " << input << endl;
}
Explanation for: while((findPos = input.find_first_of(search, findPos)) != string::npos)
input.find_first_of(search, findPos) find the first place where the searched char lies. When the char doesn't found it returns string::npos (18446744073709551615)
So we loop so long the return value is not string::npos: != string::npos
Edit to answer comment question:
Possibilities to iterate through a string:
std::string str = "aabaaba";
for(char& c : str) {
if(c == 'a'){
//it's a
} else if(c == 'b') {
//it's b
}
}
std::string str = "abaaba;
for(std::string::iterator it = str.begin(); it != str.end(); ++it) {
if(*it == 'a'){
//it's a
} else if(*it == 'b') {
//it's b
}
}
For every character in string
THANKS for all the answers!, you were big help, this code will do for me, going to go research what it does x.x
std::string str = "abaaba;
for(std::string::iterator it = str.begin(); it != str.end(); ++it) {
if(*it == 'a'){
//it's a
} else if(*it == 'b') {
//it's b
}
}

C++ Multiple delimiters with more than one char

In c++, I'm having trouble coding multiple delimiters with single char delimiters and string delimiters (e.g. "<=" as a delimiter as opposed to '='). The code below works with single char delimiters (I've set the delimiters as space, comma, dot, plus and equal) and separates the words in string line nicely. However, I don't know how to add string delimiters to this code.
std::string delimiters = " ,.+=";//I want "<=" added as a single delimiter
std::string line = "this+is,a.string=testing one";
std::size_t prev = 0, pos;
while ((pos = line.find_first_of(delimiters, prev)) != std::string::npos)
{
if (pos > prev)
{
cout << line.substr(prev, pos-prev) << endl;
prev = pos + 1;
}
}
if (prev < line.length()){
cout << line.substr(prev, std::string::npos) << endl;
}
Here is one way you could do it by erasing the delimiters you find from the line_copy string, having a special if statement for the special delimiter. Full example here:
auto pos = find_first_of(begin(line_copy), end(line_copy), begin(delimiters),
end(delimiters));
while (pos != line_copy.end()) {
if (pos != line_copy.end()) {
if (*pos == '<' && *(pos + 1) == '=') {
cout << "delimiter: \'";
cout << string(pos, pos + 2) << "\'" << endl;
// remove the delimiters from copy string
line_copy.erase(pos, pos + 2);
}
else {
cout << "delimiter: \'" << *pos << "\'" << endl;
// remove the delimiters from copy string
line_copy.erase(pos, pos + 1);
}
}
cout << endl;
pos = find_first_of(begin(line_copy), end(line_copy), begin(delimiters),
end(delimiters));
}
I would change the line
rev = pos + 1
in the following way:
if (pos > prev)
{
cout << line.substr(prev, pos-prev) << endl;
prev = line.find_first_not_of(delimiters, pos))
}
So once you hit a delimiter then you move to the fiurst char not being a delimiter.
Do a two character search one by one.
Search for "<" first and if found search for an immediate "=" if found, do substr otherwise continue searching.

How to count unique words in string and output line where they occur? C++

So I'm working on this homework assignment and I'm really having trouble. I'm supposed to count the number of words more than two characters(have to contain one letter), unique words, and the number of times each unique word appears in the Programming Execution Environment. I'm also supposed to get input to search for in the PEE and output the number of times it appears and the line where it appears. I have some of it working, but I'm really struggling with counting how many times each word appears. I know my code is really bad right now, but that's why I'm here. I'm really struggling with these string functions for some reason. Any help is really appreciated!
#include <iostream>
#include <cstring>
#include <string>
#include <cctype>
#include <algorithm>
#include <vector>
#include <set>
using namespace std;
//PEE string
string envstr("");
bool checkChar(unsigned c)
{
return (ispunct(c) || isspace(c) || isblank(c) || isdigit(c) || c == '\n');
}
void searchWord(unsigned c, size_t length)
{
multiset<string> words;
vector<string> vwrds; //this was something i was trying out
string tempword;
while (!checkChar(envstr[c]) && c < length)
{
tempword = tempword + envstr[c]; //problem here
c++;
}
tempword = tempword + " ";
vwrds.push_back(tempword);
words.insert(tempword); //this is just a bunch of random letters
tempword.clear();
//for (multiset<string>::const_iterator i(words.begin()), end(words.end()); i != end; i++)
//cout << *i;
}
bool checkIfWord(char c)
{
bool valid = false;
int i;
for (i = c; i > c - 2; i--)
{
if (!checkChar(envstr[i]))
valid = true;
}
if (valid)
searchWord(i, envstr.length());
return valid;
}
int main()
{
//this code given by my instructor
extern char **environ; // needed to access your execution environment
int k = 0;
size_t wordCount = 0;
while (environ[k] != NULL)
{
cout << environ[k] << endl;
string str(environ[k]);
envstr = envstr + str;
k++;
}
//iterator to count words
wordCount = count_if(envstr.begin(), envstr.end(), checkIfWord);
cout << "\nThe PEE contains " << wordCount << " words. \n";
//transform environment string to lowercase
transform(envstr.begin(), envstr.end(), envstr.begin(), tolower);
string input;
do
{
cout << "Enter your search item: \n";
cin >> input;
//string can only be forty characters
if (input.length() > 40 || input == "\n")
{
cout << "That search query is too long. \n";
continue;
}
//change the search string to lowercase, like the envstr
transform(input.begin(), input.end(), input.begin(), tolower);
int j = 0;
int searchCount = 0;
vector<size_t> positions;
size_t pos = envstr.find(input, 0);
//search for that string
while (pos != string::npos)
{
positions.push_back(pos);
pos = envstr.find(input, pos + 1);
searchCount++;
}
cout << "\nThat phrase occurs a total of " << searchCount << " times.\n";
cout << "It occurs in the following lines: \n";
//output where that string occurs
for (vector<size_t>::iterator it = positions.begin(); it != positions.end(); ++it)
{
for (int i = *it; i < envstr.length() - 1 && checkChar(envstr[i]); i++)
{
cout << envstr[i];
}
cout << endl;
}
positions.clear();
} while (input != "END");
cin.get();
return 0;
}
First, your function checkChar() returns false when the parameter is a char, so if you want to print where that string occurs, it should be:
for (int i = *it; (i < envstr.length() - 1) && !checkChar(envstr[i]); i++)
{
cout << envstr[i];
}
Second, the code for counting words makes no sense and there is a potential out-of-bounds here: if (!checkChar(envstr[i])), I would suggest you to split the string using delimter '\', then do something.

C++ - Replacing "_" with a character

Using C++, I'm trying to make a hangman game to become better at using C++ and programming in general. Anyways, the issue I'm facing is that I'm not sure how to replace the dashes within a string with the letter the user has guessed.
I think my problem is with the fact the word chosen is randomly chosen from an array and I'm not sure how to go about finding the positions within the randomly chosen string which consists of the guessed character.
I have commented out the area that's causing the issue.
#include <iostream>
#include <array>
#include <string>
#include <stdlib.h>
#include <time.h>
#include <cstddef>
#include <algorithm>
using namespace std;
int main()
{
string words[3] = {"stack", "visual", "windows"};
string guess;
cout << "Welcome to hangman.\n";
cout << "\n";
srand(time(NULL));
int RandIndex = rand() % 3;
string selected = words[RandIndex];
for (int i = 1; i <= selected.size(); i++) {
cout << "_ ";
}
cout << "\n";
cout << "\nType in a letter: ";
cin >> guess;
cout << "\n";
if (selected.find(guess) != string::npos) {
/*for (int i = 1; i <= selected.size(); i++) {
if (selected.find(guess) != string::npos) {
cout << "_ ";
} else {
cout << guess << " ";
}
}*/
} else {
cout << "\nNay!\n";
cout << "\n";
}
cout << "\n";
cout << "\n";
system("PAUSE");
return 0;
}
I was thinking about using the replace() function but the problem I face here is that I'm not replacing the string within selected variable but sort of iterating through the word itself, if that made any sense whatsoever?
Use a second string, that is initialized with the underscores. If the find function doesn't return string::npos it returns the position in the string, and this is the same position you should change in the string with the underscores as well.
You actually need to use a second string to store the "guessed" string; this is because you need to keep track of all the guessed letters and display them.
something like :
string s ="test";
string t=""; //empty string
for(int i=0;i<s.size();i++)
t.append("_"); //initialize the guess string
cout<<t<<'\n';
char c;
cin >> c;
int pos = s.find(c); //get the first occurrence of the entered char
while(pos!=-1) //look for all occurrences and replaced them in the guess string
{
t.replace(pos,1,1,c);
pos = s.find(c, pos+1);
}
I think you need to maintain some extra state while looping - to keep track of which letters have / haven't been guessed.
You could add a new string current_state which is initially set to the same length as the word but all underscores. Then, when the player guesses a letter, you find all instances of that letter in the original word, and replace the underscore with the letter guessed, at all the positions found but in current_state.
First i would initialize a new string to show the hidden word:
string stringToDisplay = string( selected.length(), '_');
Then For each letter given by the user i would loop like this:
(assuming guess is letter)
size_t searchInitPos = 0;
size_t found = selected.find(guess, searchInitPos));
if (found == string::npos)
{
cout << "\nNay!\n";
cout << "\n";
}
while( found != string::npos)
{
stringToDisplay[found] = guess;
searchInitPos = found+1;
found = selected.find(guess, searchInitPos));
}
cout << stringToDisplay;
Hope this will help
I think it should be that:
string words[3] = {"stack", "visual", "windows"};
char guess;
string display;
cout << "Welcome to hangman.\n";
cout << "\n";
srand(time(NULL));
int RandIndex = rand() % 3;
string selected = words[RandIndex];
for (int i = 0; i < selected.size(); i++) {
display.insert(0, "_ ");
}
cout << display;
while(display.find("_ ") != string::npos) {
cout << "\n";
cout << "\nType in a letter: ";
cin >> guess;
cout << "\n";
bool flag = false;
for (int i = 0; i < selected.size(); i++) {
if (selected[i] == guess) {
display.replace(i*2, 1, 1, guess);
flag = true;
}
}
if (!flag) {
cout << "\nNay!\n";
cout << "\n";
} else {
cout << display;
}
}