Searching through a text files for a certain word C++ - c++

I'm trying to create a searchable recipe database by ingredient for a project. I'm trying to create the for loop that goes through the string vector (which has each ingredient saved to it) and search through the file and compare them. Right now, I just want it to output "Hello!" if theres a match. With all my fiddling, theres either 100 Hello!s (definitely not right) or none. Here's the code:
int main()
{
int y;
cout << "Hello! Welcome to Abby's Recipe Calculator." << endl << endl;
cout << "Please select an option: 1 to search by ingredient or 2 to browse recipes..." << endl;
cin >> y;
vector <string> ingreds;
ingreds.reserve(4);
if (y == 1)
{
ingredientvector(ingreds); // calls function to fill vector w/ ingredients
}
//else if (y == 2)
//{
//call recipe function...
//}
Search x1(ingreds); //assigns ingredients to object vector
recipesearch(x1.getingreds());
system("pause");
return 0;
}
void ingredientvector(vector<string>& x)
{
cout << "SEARCH BY INGREDIENT" << endl;
cout << "Please enter up to three ingredients... " << endl;
for (int i = 0; i < 4; i++)
{
x.push_back(" ");
getline(cin, x[i]);
if (x[i] == "1")
{
break;
}
}
}
void recipesearch(const vector<string>& ingredientlist) //ifstream& recipes)
{
ifstream myrecipes;
string line;
string ingredient;
myrecipes.open("recipes.txt");
if (myrecipes.is_open())
{
for (int i = 0; i < 4; i++)
{
ingredient = ingredientlist[i];
while(getline(myrecipes, line)){
if (ingredient == line)
{
cout << "Hello!" << endl;
}
else
{
break;
}
}
}
}
else cout << "Unable to open recipe file!";
myrecipes.close();
}
Here is an example of a recipe used:
Cheese-y Ramen
Prep Time: 5 minutes
Cook Time: 20 minutes
Total Time: 25 minutes
Servings: 2
Ingredients:
8 oz cheddar cheese
1 tablespoon cornstarch
¾ cup milk
2 packages ramen noodles
Directions:
1. Grate cheddar cheese and add with cornstarch into a small bowl
2. Combine with milk in a medium saucepan and cook on medium to low heat until consistent. Keep warm until serving.
3. In a separate pan boil ramen noodles. Set aside the included flavor packets.
4. Once boiling, drain the noodles and combine with cheese.
Recipe from Buzzfeed

This reads the entire recipe file into a string, then looks inside the string for each ingredient. Note: This is extremely brute force. It's fast, but not going to be very accurate. For example, if Cheetos are mentioned in a side bar, not in the recipe itself, they will still be listed.
Credit where it's due, this answer lifts the file read wholesale from Read whole ASCII file into C++ std::string
void recipesearch(const vector<string>& ingredientlist)
{
ifstream myrecipes;
string file;
myrecipes.open("recipes.txt");
if (myrecipes.is_open())
{
// read entire file into string
myrecipes.seekg(0, std::ios::end);
file.reserve(myrecipes.tellg());
myrecipes.seekg(0, std::ios::beg);
file.assign((std::istreambuf_iterator<char>(myrecipes)),
std::istreambuf_iterator<char>());
// look inside file string for each ingredient
for (const string & ingredient: ingredientlist)
{
if (file.find(ingredient) != file.npos)
{ // found ingredient in file
cout << ingredient << endl;
}
}
}
else
cout << "Unable to open recipe file!";
}
Caveat: A lot of files you'll pull from the web are in encoded in a multi-byte character set to get prettier results and internationalization, not the 7 bit ASCII used by default by most of the standard C++ tools, including the those used in the above example code.
Correctly interpreting which of potentially many multi-byte character sets to use and how to consume them is a discussion topic unto itself, but for the purposes of this assignment OP may be able to get away with ensuring all input files are saved with ASCII encoding.

Try inverting the while and the for loop like such:
...the code before your for loop
while(getline(myrecipes, line))
{
for (int i = 0; i < 4; i++)
{
ingredient = ingredientlist[i];
if (ingredient == line)
{
cout << "Hello!" << endl;
}
else
{
break;
}
}
}
...the code after your for loop

Related

C++: How to display the last five names/lines when reading from a file?

I've been trying to get this function to read the last five lines of a file. This is all I have so far. A similarly structured function that finds the first five lines and displays them worked fine and so does the part of this function that counts up the total number of lines.
Everything else seems to work fine except this part and I'm not sure what I'm doing wrong. I tried multiple different solutions (aka just moving the code around and deleting lines to see if it would help) but nothing worked. It can, however, display 46-50 with the colons but not the last five lines. If I were to display the names before the for loop part and within the while loop counting part, it would successfully display all of the names.
Help would be appreciated.
Thanks. (sorry if I'm not formatting this correctly)
void displayLastFive(ifstream & fin)
{
char name[81];
int totalNumberOfLines = 0;
fin.getline(name, 81);
fin.clear();
fin.seekg(0L, ios::beg);
while (!fin.eof())
{
fin.getline(name, 81);
totalNumberOfLines++;
}
for (int i = totalNumberOfLines - 5; i < totalNumberOfLines; i++)
{
fin.getline(name, 81);
cout << i + 1 << ": " << name << endl;
}
cout << endl;
}
answer was much simpler than I thought
void displayLastFive(ifstream & fin)
{
char name[81];
int totalNumberOfLines;
totalNumberOfLines = count(fin);
fin.clear();
fin.seekg(0L, ios::beg);
for (int i = 0; i < totalNumberOfLines; i++)
{
fin.getline(name, 81);
if (i >= totalNumberOfLines - 5)
{
cout << i + 1 << ": " << name << endl;
}
}
cout << endl;
}

checking for the \n character, but nothing after that

We are working on trying to get a simple program to either say a turtle has laid eggs or not, based on user input.
The turtle starts with 8 eggs and only lays one when the user presses Enter. ('\n').
We have finally got it to work in the sense that if we press Enter, it will say the turtle lays an egg and counts down to 0 eggs left. It will also say that no egg was laid if you type anything else.
The issue we are having is to keep it from returning the 'else' statement multiple times if someone inputs more than one incorrect character we used the cin.ignore command.
However, we questioned what would happen if we only put in cin.ignore(10, '\n'), and the input was more than 10 characters. The answer is that it repeats the 'else' statement of not laying an egg.
Is there a way to just clear the input stream after the first character so the input can be as much as they want, and it will still only return one line (either laid an egg or not) for each input?
Here is the code.
int main()
{
using namespace std;
int eggs = 8;
char input;
while (eggs > 0)
{
cout << "Enter input: ";
cin.get(input);
if (input == '\n')
{
cout << "Raphie laid an egg because you pressed enter.\n";
eggs--;
cout << "She has " << eggs << " left.\n";
}
else
{
cout << "Raphie didn't lay an egg.\n";
cin.ignore(10, '\n');
}
}
return 0;
}
You can use...
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
...to ignore any amount of input before the newline.
Well usually you'd want to either read in lines or single characters. Notice how '\n' fits in both categories.
If you still want (or have) to stick with ignoring characters, you could try ignoring exactly numeric_limits<streamsize>::max(), which is the maximum number of characters in a stream at any given time.
int main()
{
using namespace std;
int eggs = 8;
char input;
while (eggs > 0)
{
cout << "Enter input: ";
cin.get(input);
if (input == '\n')
{
if (eggs > 0)
{
cout << "Raphie laid an egg because you pressed enter.\n";
eggs--;
cout << "She has " << eggs << " left.\n";
}
}
else
{
cout << "Raphie didn't lay an egg.\n";
cin.ignore(10, '\n');
}
}
return 0;
}

Deleting content from a file [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I am making a program that allows a user to make bank accounts and save them too a file, you can also delete them. I am having issues with my code for deleting an account on the file, my function for deleting the account looks like this.
int deleteCustomer(account acc[], int numCust)
{
string target;
bool accFound = false;
int count = 0;
cout << "Enter account number: ";
cin >> target;
for (int i = 0; i < numCust; i++)
{
if (acc[i].acctNum == target)
{
accFound = true;
break;
}
count++;
}
if (accFound == false)
{
cout << "That account does not exist." << endl;
system("pause");
system("cls");
}
else if (accFound == true)
{
ofstream outFile;
outFile.open("customer.dat");
for (int i = count; i < numCust - 1; i++)
{
outFile << acc[i+1].acctNum;
outFile << '#';
outFile << acc[i+1].name;
outFile << '#';
outFile << acc[i+1].cBal;
outFile << '#';
outFile << acc[i+1].sBal;
outFile << '#';
}
numCust--;
outFile.close();
}
return numCust;
}
The function is supposed to overwrite the account selected by the user by saving the file ahead of it to the previous spot and return the new number of customers. It appears to run through fine but it does not do anything and I am uncertain as to why. Any input would be helpful, thank you.
Several problems here:
Your account lookup should be working, but you're overcomplicating this a bit (you'd only need one value rather than three, but let's skip that for now). If you're interested let me know.
You're never actually removing any account (just reducing the number of total accounts; which will then cause the last entry to be removed).
When saving you accounts to the file, you start at that selected index, which doesn't make any sense at all.
Let's assume you've got 10 accounts, indices 0 through 9.
The user picks the account at index 5.
You save accounts index 6 through 9(!) only.
The user picks the account at index 0.
You save accounts index 1 through 9 only.
Some style things:
You essentially store the selected account's index in count. That's fine, but very misleading. Don't ever use misleading variable names. As you might be able to tell from my comment above, I misread that part as well.
Rather than writing if (booleanValue == true) you could just write if (booleanValue), which results in the same code, but is shorter and might be faster to read. In a similar way, you could replace if (booleanValue == false) with !booleanValue.
Don't omit namespaces like std, if you can (e.g. use std::string rather than string and avoid using namespace std;) to avoid writing ambigious code. If some other namespace you use has string (or any other member) as well, you'll either have to explicitly name the namespace anyway or you're at least confusing others reading your code. Also there's always the potential bug introduced by unintentionally using a different type.
Fixing the actual problem:
I assume this is some homework assignment or some tutorial/class code or anything similar? If so, don't just copy the following code and instead try to think about how it's working. Once you understood, implement it yourself and only use my snippets if you're really stuck.
In general, it's good software design to keep code and functions minimal. Don't create "super functions" that do several things. Also try to make code reusable, so in case you change something, you're able to adjust it in one place only.
Take your code above for example. Whenever you add, delete, or update an account, you'll have to write the new file. Did you plan on replicating the same code multiple times? If you'd have to adjust your file format, you'd have to change it everywhere.
You'll also need some way to actually remove customer datasets. As you might be aware, deleteing entries in an array would require you to move all entries behind it (to keep it continguous). This can be a very expensive operation.
To avoid this, I'm adding a new member bool valid to account. By default, this is set to false. Once there's some data put there (either through reading from a file or by the user), it's value is set to true.
So instead split this into two separate functions (moving the common code - saving - to its own function):
// By returning an integer value, you're able to communicate issues or problems
// without having to rely on exceptions (in case you're using C++).
// Note that I don't do any error checking here for simplicity.
// Parameters:
// filename - the target file to write
// acc - the array holding all customer accounts
// size - the maximum amount of values in acc
// Return value: 0, if everything went fine
// (I skipped actual error handling to keep it simple!)
int saveCustomers(const char *filename, account acc[], int size) {
std::ofstream outFile(filename);
// Iterate over all entries
for (int i = 0; i < num; ++i) {
// Do we actually have to store the account?
if (acc[i].valid) {
outfile << acc[i].acctNum << '#' << acc[i].name; // write all the values the way you did
}
}
outFile.close();
return 0; // Everything ok
}
Now that this is done, you're able to create your functions to modify your customer data:
int deleteCustomerByNumber(account acc[], int num, std::string target) {
// Iterate over all accounts and look for the selected one
for (int i = 0; i < num; ++i) {
// Only check valid accounts and see whether it's the target
if (acc[i].valid && acc[i].acctNum == target) {
acc[i].valid = false; // Mark it as invalid
return 0; // Everything ok
}
}
return 1; // Didn't find it!
}
In a similar way you can look for empty/unused entries to actually write data to them.
Bonus - alternative (STL) approach:
Since you're using C++, I'd suggest you use a different data structure, not just a simple array:
If you use a STL container (more specific: a map), you're able to handle everything a lot easier.
#include <map>
// Create a typedef to simplify expressions
typedef std::map<std::string, account> accmap;
// All accounts would be stored in this object:
accmap accounts;
// To do a quick lookup of any account:
accmap::const_iterator a = accounts.find(accountNumber);
if (a == accounts.end())
;// Account not found!
else {
a->first; // This is your account number
a->second; // This is your `account` object
}
// To delete a specific account:
accounts.erase(accountNumber)
// To create a new account simply access it:
accounts[accountNumber].name = newName;
You need to save all of the records before the index and after the index, otherwise you are effectively deleting more than just the one account. Presumably you should also remove the record from the input array as well. You are also not doing any error handling on the input or output. And you need to fix your output loop, it is not using indexes correctly.
Try this:
int deleteCustomer(account acc[], int numCust)
{
string target;
int accFound = -1;
cout << "Enter account number: ";
if (cin >> target)
{
for (int i = 0; i < numCust; ++i)
{
if (acc[i].acctNum == target)
{
accFound = i;
break;
}
}
}
if (accFound == -1)
{
cout << "That account does not exist." << endl;
system("pause");
system("cls");
}
else
{
for (int i = accFound+1; i < numCust; ++i)
acc[i-1] = acc[i];
--numCust;
ofstream outFile;
outFile.open("customer.dat");
for (int i = 0; (i < numCust) && (outFile); ++i)
{
outFile << acc[i].acctNum;
outFile << '#';
outFile << acc[i].name;
outFile << '#';
outFile << acc[i].cBal;
outFile << '#';
outFile << acc[i].sBal;
outFile << '#';
}
if (!outFile)
cout << "Error saving customer file" << endl;
}
return numCust;
}
If you don't want to update the array, then you can do this instead:
int deleteCustomer(account acc[], int numCust)
{
string target;
int accFound = -1;
cout << "Enter account number: ";
if (cin >> target)
{
for (int i = 0; i < numCust; ++i)
{
if (acc[i].acctNum == target)
{
accFound = i;
break;
}
}
}
if (accFound == -1)
{
cout << "That account does not exist." << endl;
system("pause");
system("cls");
}
else
{
ofstream outFile;
outFile.open("customer.dat");
for (int i = 0; (i < numCust) && (outFile); ++i)
{
if (i != accFound)
{
outFile << acc[i].acctNum;
outFile << '#';
outFile << acc[i].name;
outFile << '#';
outFile << acc[i].cBal;
outFile << '#';
outFile << acc[i].sBal;
outFile << '#';
}
}
if (!outFile)
Cout << "Error saving customer file" << endl;
--numCust;
}
return numCust;
}
Lastly, when updating a file, it is a good idea to write the new data to a temp file first, then replace the original file with the temp file only if everything is successful. That way you reduce the risk of corrupting the original file.
To "deleting an account on the file", this part of code:
for (int i = count; i < numCust - 1; i++)
{
outFile << acc[i+1].acctNum;
outFile << '#';
outFile << acc[i+1].name;
outFile << '#';
outFile << acc[i+1].cBal;
outFile << '#';
outFile << acc[i+1].sBal;
outFile << '#';
}
should be
for (int i = 0; i < numCust; i++)
{
if(i == count) continue;// remove the account user selected
outFile << acc[i].acctNum;
outFile << '#';
outFile << acc[i].name;
outFile << '#';
outFile << acc[i].cBal;
outFile << '#';
outFile << acc[i].sBal;
outFile << '#';
}

Skipping lines and not leaving them blank w/ ofstream

I have a pretty basic ofstream() question. I have an app that matches data that was inputted by a user in a text document. Can i skip lines with ofstream and not modify text already there? If possible, how? Please forgive me my English isn't too great.
#include <fstream>
#include <iostream>
#include <string>
using namespace std;
int main()
{
int count = 0;
int num;
int numcopy;
string clientNames[3000];
string caseNumbers[3000];
int userInp = 1;
string confirm = "2";
cout << "Do you have a file already started (y/n)?"<<endl;
cin >> confirm;
if(confirm == "y")
{
goto input;
}
if(confirm == "n")
{
goto postinput;
}
input:
cout << "What is the number of the query last entered?";
cin >> userInp;
num = userInp;
numcopy = userInp;
postinput:
for(int i = 1; i <3000; i++)
{
userInp ++;
repeat:
cout <<"Enter Client's Name:";
cin >> clientNames[userInp];
cout << " " <<endl;
cout <<"Enter Case Number:";
cin>> caseNumbers[userInp];
cout <<"Client Name "<< i << " "<<clientNames[userInp]<<endl;
cout << "Case Number" << i << " "<<caseNumbers[userInp]<<endl;
cout <<"Is This Correct?"<<endl;
confirm == " ";
cin >> confirm;
if(confirm == "y")
{
cout <<"Confirmed"<<endl;
}
if(confirm == "n")
{
goto repeat;
}
if(confirm == "/end")
{
break;
}
}
ofstream file;
file.open("caseData.txt");
for(int w = 0; w <3000;w++)
{
num++;
file <<
}
}
"skip lines with ofstream and not modify text already there" is not possible.
But you can store all lines of the file in your program first. And while you are processing the file, output the stored line when you want to leave that line unchanged.
This effectively does what you want.
Also, you really should get rid of the gotos in your code. They should be used only in rare cases. And for beginners, I always feel they should not use it until they are very familiar with programming.
I am going to take a guess that you want to do something about the circumstance when the user has inputted the same clientName or same caseNumber multiple times. It is actually not entirely clear from your question that this is what you want to do, but you asked:
I have an app that matches data that was inputted by a user in a text document. Can i skip lines with ofstream and not modify text already there? If possible, how?
However, I did not see any matching logic in your program. You are simply recording up to 2999 entries (since you don't use the 0 entry of your arrays), or wait until the user enters /end as a confirmation message.
If you had actual matching logic, you could detect on input whether the user has typed in the same clientName or same caseNumber, and you can prompt the user for what to do about it (for example, keep the old existing entry, keep newly entered entry). If you had such logic, you would know that you would only be outputting unique lines of data, and so your output loop would be fairly simple.
There were some comments made on your use of goto. Instead of the repeat: label, you could start another loop:
//repeat:
do {
// ...read in input, echo it back, wait for confirmation...
cin >> confirm;
if (confirm == "y") {
cout << "Confirmed" << endl;
break;
}
} while (confirm != "/end");
if (confirm == "/end") {
break;
}
In this code, anything other than a y or /end is treated the same as n.

Using vectors to bleep some predefined strings

So i'm currently doing the exercices in my programming book "Programming: Principles and practice using c++" from Bjarne Stroustrup and i'm curently stuck at one exercice. Basically, the exercice is to write a program that bleeps out words it doesn't like. The way it works is that the user inputs a string and the program repeats the word. If the word the user enters is part of the dislike vector, the word is replaced by "Bleep". (I don't know if I explained this right, but it shouldn't be to complicated to understand).
This is my version of the program:
int main()
{
string dislike = "Potato";
string words = " ";
cout << "Please enter some words: " << endl;
while(cin>>words)
{
if(words==dislike)
{
cout << "Bleep!" << endl;
}
else
{
cout << words << endl;
}
}
system("pause");
return 0;
}
As you can see, this version isn't using vectors (and it should, because the exercice is right after the explanation of vectors in the chapter). So my question is, how can I implement a vector with many "dislike" words in it like this:
vector<string>dislike;
dislike.push_back("Potatoes");
dislike.push_back("Peanuts");
dislike.push_back("Coconut");
and make it so it works like my other version without vectors (repeats words, but bleeps the dislike words). I can't seem to understand how to navigate in a vector so that it only bleeps the "dislike" words.
If someone could give me a hand and explain to me how it works (please do not just give me the answer) it would be very appreciated.
Thank you for your time and help, learning c++ alone isn't always simple, and I thank this website for making my learning curve a bit easier.
bobicool
Ok, let me explain a simple approach to it. There are more elegant ones, but for now it's important that you get a feeling of how std::vector can be accessed and how to compose control structures correctly.
Step 1 - looping through all elements of a vector
You can use iterators to go through all elements of a vector.
for(vector<string>::const_iterator it = dislike.begin(); it != dislike.end(); ++it) {
// now *it gives access to the current element (here: current dislike word)
if (*it == words) {
// ... yeah, we found out the current word is on the list!
}
}
You get an iterator to the first element in a vector by calling begin(), then keep incrementing (++it) it until you reached the end of the vector. I use const_iterator here because I'm not going to modify any elements, if you need to, use iterator.
with a std::vector, indexing via [index] is also possible (but not recommended, usually):
for(size_t i = 0;i < dislike.size(); ++i) {
// dislike[i] is the current element
if (dislike[i] == words) {
// huuuuray! another BEEEP candidate
}
}
Step 2 - break the loop early
As soon as you know what for sure that we have a dislike word, you don't need to search the vector further.
for(vector<string>::const_iterator it = dislike.begin(); it != dislike.end(); ++it) {
if (*it == words) {
// we found a positive match, so beep and get out of here
cout << "Bleep!" << endl;
break;
}
}
Step 3 - make a note if we handled a word already
bool is_beep = false;
for(vector<string>::const_iterator it = dislike.begin(); it != dislike.end(); ++it) {
if (*it == words) {
// we found a positive match, so beep and get out of here
cout << "Bleep!" << endl;
is_beep = true;
break;
}
}
// this is not a dislike word if is_beep is false, so print it as usual
if (!is_beep) {
cout << words << endl;
}
Step 4 - putting it all together
int main()
{
vector<string>dislike;
dislike.push_back("Potatoes");
dislike.push_back("Peanuts");
dislike.push_back("Coconut");
string words = " ";
cout << "Please enter some words: " << endl;
while(cin>>words)
{
bool is_beep = false;
for(vector<string>::const_iterator it = dislike.begin(); it != dislike.end(); ++it) {
if (*it == words) {
// we found a positive match, so beep and get out of here
cout << "Bleep!" << endl;
is_beep = true;
break;
}
}
// this is not a dislike word if is_beep is false, so print it as usual
if (!is_beep) {
cout << words << endl;
}
}
system("pause");
return 0;
}
Check out std::find for a more idiomatic solution - it basically saves you the inner loop. You can also get rid of that bool in the last code sample if you re-structure a bit. I'll leave that as an exercise to you (hint: keep the iterator alive and check out its value after terminating the loop).
int main()
{
vector<string> dislike;
dislike.push_back("Potatoes");
dislike.push_back("Peanuts");
dislike.push_back("Coconut");
string words;
cout << "Please enter some words: " << endl;
while(cin >> words)
{
if(find(dislike.begin(), dislike.end(), words) != dislike.end())
{
cout << "Bleep!" << endl;
}
else
{
cout << words << endl;
}
}
system("pause");
return 0;
}
For std::find add #include <algorithm> to your source.
use std::find(your_vector.begin(), your_vector.end(), words)
int main()
{
vector<string>dislike;
dislike.push_back("Potatoes");
dislike.push_back("Peanuts");
dislike.push_back("Coconut");
string words = " ";
cout << "Please enter some words: " << endl;
while(cin>>words)
{
if(std::find(dislike.begin(), dislike.end(), words) != dislike.end())
{
cout << "Bleep!" << endl;
}
else
{
cout << words << endl;
}
}
system("pause");
return 0;
}
Here is my solution to that particular question in the book when i was reading it. :) hope it's self-explanatory.
/*THE QUESTION GOES LIKE;
Write a program that “bleeps” out words that you don’t like; that is, you read in words
using cin and print them again on cout. If a word is among a few you have defined, you
write out BLEEP instead of that word. Start with one “disliked word” such as string
disliked = “Broccoli”;
When that works, add a few more.*/
#include "std_lib_facilities.h" // this is a standard library header that came with
the book
int main () {
vector<string> dislike = {"Dislike", "Alike", "Hello", "Water"}; /* defining a vector
for the disliked words. */
vector<string> words; //initializing vector for the read words.
cout << "Please enter some words\n"; //prompt user to enter some words.
for( string word; cin >> word;) //this current word typed is read in.
words.push_back(word); // word read in are pushed into the vector "words".
sort(words); /* function for the standard library for sorting data...this makes the data from the vector "words" appears in alphabetical order. */
for (int i=0; i<words.size(); ++i){ /*this acts as an iterator. and goes through all the element of the vector "words". */
if(i==0 || words[i-1]!=words[i]){ /*this prevents the words from repeating....just an option incase the user enters same kinda words twice or more. */
if(words[i]!=dislike[0] && words[i]!=dislike[1] && words[i]!=dislike[2] && words[i]!=dislike[3]) /*This test checks whether the words typed match any of the elements of the vector "dislike".if they don't match; */
cout << words[i]<< '\n'; //prints out the words.
else
cout << "BlEEP!\n"; //if they match....print out "BlEEP!".
}
}
}
I am learning C++. This Program has been changed some.
Write a program that "bleeps" out bad words that you don't like; that is,
you read in words using cin and print them again on cout. If a word is among a few you have defined, you write out BLEEP and or have it to BLEEP(Sound) instead of that word. Start with one "bad word" such as -- string badword = "arse"; When that works, add a few more or write a whole program based on all the bad words that you do not want printed out.
while (cin >> words)
{
if(find(badwords.begin(), badwords.end(),words) !=badwords.end())
{
cout << " " << endl; // You can put Bleep in or leave it out (Blank) if blank
// it will leave a blank in the phrase when it prints
Beep(523,500); // This is to Bleep (Sound) when a bad word is found
cin.get();
}
else
{
cout << words << endl;
}
}
Since someone gave the answer I have Changed the program some. That is for you to learn.
This runs on Visual Studio Express 2012
I have solved this problem using the ideas that have already been learned in the previous chapters, not going beyond what you understand.
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<string> disliked;
//adding disliked words to the vector
disliked.push_back("dog");
disliked.push_back("cat");
disliked.push_back("goat");
disliked.push_back("cow");
disliked.push_back("sheep");
disliked.push_back("pig");
string words=""; //this variable will store the input from the user.
while(cin>>words)
{//test every entered word to see if it's equal to any word listed in disliked words.
if(words==disliked[0] ||//or
words==disliked[1] ||//or
words==disliked[2] ||//or
words==disliked[3] ||//or
words==disliked[4] ||//or
words==disliked[5]){
cout<<"Bleeps";}
else{
cout<<words;}
}
return 0;
//Not that I have not gone beyond what has been covered in the previous chapters.
//I know their are beautiful solutions to this problem.
//Keep learning you will know everything.
}
This question was asked a long, long time ago so the author is probably professional at this point lol, but here is simpler yet working solution for anybody who is looking for the same answer. I am learning from the beginning through Bjarne book so im not yet "affected" with higher knowledge to confuse you with but with solutions that are good enough to work based on how far we are in the book. :)
// program that bleeps out words we dont like
vector <string> words;
vector <string> bwords = {"this", "that", "then"}; //bleeped words
string sword; // temporary word
cout << "Enter few words: ";
for (string tword; cin >> tword;) // read in words
words.push_back(tword);
//check if they match beeped words
cout << "\n\nWords:\n";
for (int i = 0; i < words.size(); i++) //take word[i] from the vector
{
sword = words[i]; // temporary variable is now word[i]
for (int j = 0; j < bwords.size(); j++) // take beeped word[j] from saved words
{
if (words[i] == bwords[j]) // is word[i] same as bleeped word[j]
sword = "BLEEP"; // if word[i] is same then replace sword with BEEP
}
cout << sword << "\n"; // now we checked first word and if it matches with any of the bleeped words then it will cout bleep, otherwise it will cout first word.
}
Now in this example you can add many new bleeped words and you wont need to change the code.
This is not the best solution in "real life" programming, but at this point in the book we learned for, if, vector(not a lot of it), cout, cin.. etc so anything else just looks confusing..until this point we dont know yet about using :: , begin, true/fals, cin.get or anything like that.
//Josef.L
//2019/7/11
int main(void){
vector <string> inpute;
for(string pat; cin >>pat;){
inpute.push_back(pat);
}
for(int i=0; i < inpute.size(); i++){
if("work"== inpute[i]){
cout<<"bleep! "<<endl;}
else if("life" == inpute[i]){
cout<<"bleep! "<<endl;
}
else if("broccoli" == inpute[i]){
cout<<"bleep! "<<endl;
}
else if("homework" == inpute[i]){
cout<<"bleep! "<<endl;
}
else{
cout <<inpute[i]<<endl;
}
}
return 0;}
//However, the entire source code is too long and boring, so there should be an improvement.
That's my solution, where you can add as many words as you want without changing the code.
#include "std_lib_facilities.h"
int main()
{
vector<string> dislike;
dislike.push_back("Potatoes");
dislike.push_back("Peanuts");
dislike.push_back("Coconut");
vector<string> words;
for (string temp_word; cin >> temp_word; )
{
for (int i = 0; i < dislike.size(); ++i)
{
if (temp_word == dislike[i])
{
words.push_back("BLEEP");
break;
}
else if (i == dislike.size() - 1 && temp_word != dislike[dislike.size() - 1])
{
words.push_back(temp_word);
break;
}
}
}
for (string temp_word : words)
{
cout << temp_word << ' ';
}
keep_window_open();
}
“Simple can be harder than complex: You have to work hard to get your thinking clean to make it simple. But it’s worth it in the end because once you get there, you can move mountains.” ― Steve Jobs
#include "std_lib_facilities.h"
int main()
{
vector<string>disliked;
disliked.push_back("Apple");
disliked.push_back("OliveOil");
disliked.push_back("Strawberry");
disliked.push_back("Lemon");
cout<<"Please type some words:"<<"\n";
string words=" ";
while(cin>>words)
{
if (words==disliked[0] | words==disliked[1]|
words==disliked[2] | words==disliked[3])
{cout<<"BLEEP"<<"\n";}
else{cout<<words<<"\n";}
}
keep_window_open();
}