Search word not found in a vector? - c++

I'm implementing a function where the user can search for a word in a vector. The only problem is, my search function is only finding certain words and I'm not sure why.
ifstream in("testdata.txt");
string word1;
vector<string> individual_words;
while (in >> word1)
{
individual_words.push_back(word1);
}
Inside the file testdata.txt is:
Hello how are you
Good are you well?
Snazzy piece of toast
Here is the code where I compare the two words.
string search_word;
while (cin >> search_word)
{
for (int f=0; f < individual_words.size(); f ++)
{
cout << "individual words: " << individual_words[f] <<endl;
cout << "search word: " << search_word;
if (search_word == individual_words[f])
{
cout << " FOUND THE SAME WORD\n!";
break;
}
}
}
For some reason it's only catching certain words in a .txt file and I'm not exactly sure why. I've looked at it and it looks like it ignores the first word and it ignores every last word on each sentence.

Your vector will have duplicates, so it will only find the first occurrences of the words "are" and "you" before your loop breaks. Logically, there is nothing else wrong in this section of code, though it would be better written as:
#include <algorithm>
#include <iostream>
#include <iterator>
#include <string>
#include <sstream>
#include <vector>
using namespace std;
int main()
{
// simplified for demonstration purposes
string test = "Hello how are you\nGood are you well?\nSnazzy piece of toast";
istringstream iss(test);
vector<string> words;
copy(istream_iterator<string>(iss), istream_iterator<string>(), back_inserter(words));
string search_word;
while (cin >> search_word)
{
// this works, but is unnecessary
/*for (int f=0; f < words.size(); f ++)
{
cout << "individual words: " << words[f] <<endl;
cout << "search word: " << search_word;
if (search_word == words[f])
{
cout << " FOUND THE SAME WORD\n!";
break;
}
}*/
// this is a better approach
vector<string>::iterator it = find(words.begin(), words.end(), search_word);
if (it != words.end())
{
cout << "Found the word: " << *it << endl;
}
else
{
cout << "Not found!" << endl;
}
}
return 0;
}

Related

Why am I getting an extra space on my parsing string code?

I am having problems with my code for this homework assignment. Everything is outputting correctly except I am getting an extra space after my "first" output. My code is shown below please help me to fix the extra space.
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
int main() {
string userStr;
bool inputDone = false;
while(!inputDone)
{
bool commaCheck = false;
do
{
cout << "Enter input string:" << endl;
getline(cin, userStr);
if (userStr == "q")
{
inputDone = true;
break;
}
else{
for (unsigned int i = 0; i < userStr.length(); i++)
{
if (userStr[i] == ',')
commaCheck = true;
}
if (!commaCheck)
{
cout << "Error: No comma in string." << endl << endl;
}
}
} while (!commaCheck);
if(!inputDone)
{
string first, second;
istringstream stream(userStr);
getline(stream, first, ',');
stream >> second;
cout << "First word: " << first << endl;
cout << "Second word: " << second << endl;
cout << endl;
}
}
return 0;
}
If you use std::getline(stream, first, ','); and there is a space between your word and the comma then it will be of course in first. Because you told std::getline: Get me everything until you see a comma.
If somebody inputs " a ,b", then you have leading and trailing spaces in first.
You need to "trim" your string, meaning remove leading and trailing spaces.
There are many trim functions published here on SO. Please see for example here
If you see an additional problem, then please inform

C++ Searching for a word in a CSV file

I am trying to create a program that stores data from a CSV file and then searches it for key words.
I have this code, and there are no errors shown, but it wont run the program past asking for 'Enter word: '
#include <iostream>
#include <string>
#include <fstream>
#include <vector>
#include <sstream>
using namespace std;
int main(){
vector<string> student(860);
vector<string> question(860);
vector<string> answer(860);
int count = 0;
string word;
ifstream file("data2.csv");
if (!file.is_open())
cerr << "File not found" << endl;
while (file.good()){
for (int i = 0; i < 860; i++){
getline(file, student[i], ',');
getline(file, question[i], ',');
getline(file, answer[i], ',');
}
}
cout << "Enter word: ";
cin >> word;
for (int j = 0; j < 860; j++){
if (answer[j].find(word) != std::string::npos){
cout << student[j] << question[j] << answer[j] << endl;
count++;
}
}
cout << count;
return 0;
}
In order to get std::cin to contain the exact string (multiple words?) that the user inputs, you can use std::getline() which will support more than one word specified by the user. It's not clear from your problem statement if this is what you want or not. Otherwise I don't see a problem with just using std::cin if all you're looking for is a single word of input.
std::string match;
std::cout << "Enter the exact string to search for: ";
std::getline(std::cin, match);
std::cout << "\nSearching for \"" << match << "\"" << std::endl;
Also, in your for loop for searching the answer strings, you should prefer to use the built in size of the vector you're looping through as opposed to a hard coded value.
for ( size_t j = 0; j < answer.size(); ++j )
{
std::size_t found = answer[j].find(match);
if (found != std::string::npos)
{
std::cout << "found \"" << match
<< "\" starting at character " << found << std::endl;
count++;
}
}
std::cout << "occurrences of match criteria: " << count << std::endl;
the error is in getline, the first call to it, extracts the word until the comma the second call until the 2nd comma, the 3r call to third comma past the to the next new line (the next student's name).
So the next iteration in the getline call, will fetch the question as the students name then the answer as the question then the next students name as the answer, a total mess!!! ;) So you will never find the word you are looking for, thus no result. Get it?
to fix this, try to change the last getline to getline(file, answer[i]);
So, I know this is not the best way to solve the problem. But, in a time crunch I was able to fix these few errors and add a system("pause"); at the end of my code so that it would let me see the results.
#include <iostream>
#include <string>
#include <fstream>
#include <vector>
#include <sstream>
using namespace std;
int main(){
vector<string> student(860);
vector<string> question(860);
vector<string> answer(860);
int count = 0;
string word;
ifstream file("data2.csv");
if (!file.is_open())
cerr << "File not found" << endl;
while (file.good()){
for (int i = 0; i < 860; i++){
getline(file, student[i], ',');
getline(file, question[i], ',');
getline(file, answer[i], '\n');
}
}
cout << "Enter word: ";
cin >> word;
for (int j = 0; j < 860; j++){
if (answer[j].find(word) != std::string::npos){
cout << student[j] << question[j] << answer[j] << endl;
count++;
}
}
cout << count << endl;
system("pause");
return 0;
}

How to read a vector of strings from stdin in c++

From the book "Accelerated C++":
Ex 4-5-> Write a function that reads words from an input stream and stores them in a vector. Use that function both to write programs that count the number of words in the input, and to count how many times each word occurred.
This is the code I am trying to run:
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using std::cin; using std::cout;
using std::vector; using std::sort;
using std::endl; using std::string;
using std::istream;
istream& read_words(istream& in, vector<string>& words) {
if (in) {
words.clear();
string word;
while (in >> word)
words.push_back(word);
in.clear();
}
return in;
}
int main() {
vector<string> words;
read_words(cin, words);
cout << "Num of words: " << words.size() << endl;
sort(words.begin(), words.end());
string prev_word = "";
int count = 0;
for (vector<string>::size_type i = 0; i < words.size(); ++i) {
if (words[i] != prev_word) {
if (prev_word != "")
cout << prev_word << " appeared " << count << " times" << endl;
prev_word = words[i];
count = 1;
}
else
++count;
}
cout << prev_word << " appeared " << count << " times" << endl;
return 0;
}
Now, when I try to run the code, it gets stuck at the input and keeps reading
until I abort the program using Ctrl+C. What is wrong with my code?

First word of a phrase is dropped when I try and put it in a vector?

Sorry for the vague header. Difficult to describe. I am trying to get a phrase from the user and put that phrase into a vector, word by word, separated by spaces. For some reason when the vector is printed it completely leaves out the first word of the phrase, if that makes sense. Here's the code I have so far:
void printVector(vector<string>& words){
cout << "Print words: " << endl;
for (int i = 0; i < words.size(); i++){
if (i < words.size()){
cout << words[i] << ", ";
}
else
cout << words[i];
}
cout << endl;
}
int main(){
string phraseInput;
string stop = "done";
do{
cin >> phraseInput;
if(phraseInput == stop){
cout << "Program finished." << endl;
return 0;
}
else {
getline(cin, phraseInput);
istringstream iss(phraseInput);
vector<string> words;
copy(istream_iterator<string>(iss),
istream_iterator<string>(),
back_inserter(words));
printVector(words);
}
}while(phraseInput != stop);
}
Here you have taken input for two times only first one skipped
Now you should change this
else{ string temp;
getline(cin, temp);
phraseInput+=temp;
istringstream iss(phraseInput);
//.....
I think I found your answer
I tested your code with the phrase "this is line."
Your variable "phraseInput" first take "this" string.
After getline(cin, phraseInput) line.
Your variable "phraseInput" take "is line" string.
Therefore when it prints, it simply skips the first keyword.
Result is: the first string "this" is missing
I think in this way: You take two input from user.
Therefore I thought " What happens if I commented first cin? "
After commented on your first cin. I got all the string in variable "phraseInput"
Result is:
Then I thought "do while" loop also unnecessary, since it prints any word it took from user.
I also commented your "do while" loop
Here is the final version of your code.
#include <vector>
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
void printVector(vector<string>& words){
cout << "Print words: " << endl;
for (int i = 0; i < words.size(); i++){
if (i < words.size()){
cout << words[i] << ", ";
}
else
cout << words[i];
}
cout << endl;
}
int main(){
string phraseInput;
string stop = "done";
/*do{
cin >> phraseInput;
if (phraseInput == stop){
cout << "Program finished." << endl;
return 0;
}
else {*/
getline(cin, phraseInput);
istringstream iss(phraseInput);
vector<string> words;
copy(istream_iterator<string>(iss),
istream_iterator<string>(),
back_inserter(words));
printVector(words);
//}
system("pause");
//} while (phraseInput != stop);
}

Validate case pattern (isupper/islower) on user input string

I need to write a program that checks if the user-provided first and last names are correctly typed. The program needs to validate that only the first letter of each name part is uppercase.
I managed to write code that checks the first character of the input. So I have a problem when for example "JOHN" is entered.
A correct input would be for example "John Smith".
Here's the code:
#include <iostream>
#include <string>
using namespace std;
int main ()
{
std::string str;
cout << "Type First Name: ";
cin >> str;
if(isupper(str[0]))
{
cout << "Correct!" <<endl;
}
else
{
cout << "Incorrect!" <<endl;
}
system("pause");
return 0;
}
The simplest thing you can do is to use a for/while loop. A loop will basically repeat the same instruction for a number of n steps or until a certain condition is matched.
The solution provided is pretty dummy, if you want to read the first name and last name at the same time you will have to spit the string via " " delimiter. You can achieve this result using strtok() in C/C++ or with the help of find in C++. You can see some examples of how to split here.
You can easily modify your code to look like this:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main()
{
std::string str;
std::vector<std::string> data = { "First", "Last" };
int j;
for (int i = 0; i < 2; i++) {
cout << "Type " << data[i] << " Name: ";
cin >> str;
if (isupper(str[0])) {
for (j = 1; j < str.size(); j++) {
if (!islower(str[j]))
{
cout << "InCorrect!" << endl;
break; // Exit the loow
}
}
if(j==str.size())
cout << "Correct!" << endl;
}
else {
cout << "InCorrect!" << endl;
}
}
system("pause");
return 0;
}