I need help doing a word search and count - c++

Ok so im doing a homework assignment where im suppose to read a a text file with a 100 selected words and then read another "text" file and compare how many of those 100 selected words show up on the "text" file and what is the longest and shortest words and how many time those selected words are in the text file. I need complete help this is what i got so far. by the way i still havent inputed the selected files yet so thats why those ifs statements are incomplete
#include "stdafx.h"
#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
using namespace std;
int main ()
{
int fileNumber;
string Words [100];
string wordCounts [100];
string Frequencies [100];
string shortest = "abcdefghijklmnopqrstuvwxyz";
string longest = "";
int totalWordCount = 0;
ifstream inData;
int I=0;
inData.open("SelectWords.txt");
while ( !inData.eof () ) {
inData >> Words [I];
}
int irow;
while ( irow=0, irow<=100, irow++) {
cout<<Words[I]<<endl;
}
cout<<"Choose a file you want to open"<<endl;
cout<<"1= A Modest Proposal"<<endl;
cout<<"2=Apology" <<endl;
cout<<"3=The Call of the Wild"<<endl;
cout<<"4=The Adventures of Tom Sawyer"<<endl;
cin>> fileNumber;
while ((fileNumber<1) || (fileNumber>4))
{
cout<<"Error please try again"<<endl;
cout<<"Choose a file you want to open"<<endl;
cout<<"1 - A Modest Proposal"<<endl;
cout<<"2 - Apology" <<endl;
cout<<"3 - The Call of the Wild"<<endl;
cout<<"4 - The Adventures of Tom Sawyer"<<endl;
cin>> fileNumber;
}
if (fileNumber==1)
{
}
if (fileNumber==2)
{
}
if (fileNumber==3)
{
}
if (fileNumber==4)
{
}
system ("pause");
return 0;
}

I would do something like this:
std::string filename;
switch (filenumber)
{
case 1:
filename = "modest_proposal.txt";
break;
case 2:
filename = "apology.txt";
break;
//...
}
std::ifstream target_file(filename.c_str());
if (!target_file)
{
std::cerr << "Error opening file " << filename << endl;
return EXIT_FAILURE;
}
std::string word;
while (target_file >> word)
{
// Search word list
}
Notice how I only use the switch for determining the file name. The remaining part of the algorithm is the same regardless of the file name.
Edit 1: Suggestions
Use std::map<word, count> instead of two separate arrays.
Create one text variable for the menu and print the variable twice
instead of duplicating the code.

Related

replacing string based on user input c++

i want to receive an input from user and search a file for that input. when i found a line that includes that specific word, i want to print it and get another input to change a part of that line based on second user input with third user input. (I'm writing a hospital management app and this is a part of project that patients and edit their document).
i completed 90 percent of the project but i don't know how to replace it. check out following code:
#include <iostream>
#include <stream>
#include <string.h>
#include <string>
using namespace std;
int main(){
string srch;
string line;
fstream Myfile;
string word, replacement, name;
int counter;
Myfile.open("Patientlist.txt", ios::in|ios::out);
cout << "\nEnter your Name: ";
cin.ignore();
getline(cin, srch);
if(Myfile.is_open())
{
while(getline(Myfile, line)){
if (line.find(srch) != string::npos){
cout << "\nYour details are: \n" << line << endl << "What do you want to change? *type it's word and then type the replacement!*" << endl;
cin >> word >> replacement;
}
// i want to change in here
}
}else
{
cout << "\nSearch Failed... Patient not found!" << endl;
}
Myfile.close();
}
for example my file contains this line ( David , ha , 2002 ) and user wants to change 2002 to 2003
You cannot replace the string directly in the file. You have to:
Write to a temporary file what you read & changed.
Rename the original one (or delete it if you are sure everything went fine).
Rename the temporary file to the original one.
Ideally, the rename part should be done in one step. For instance, you do not want to end up with no file because the original file was deleted but the temporary one was not renamed due to some error - see your OS documentation for this.
Here's an idea:
#include <iostream>
#include <fstream>
#include <string>
#include <cstdio>
using namespace std;
void replace(string& s, const string& old_str, const string& new_str)
{
for (size_t off = 0, found_idx = s.find(old_str, off); found_idx != string::npos; off += new_str.length(), found_idx = s.find(old_str, off))
s.replace(found_idx, old_str.length(), new_str);
}
int main()
{
const char* in_fn = "c:/temp/in.txt";
const char* bak_fn = "c:/temp/in.bak";
const char* tmp_fn = "c:/temp/tmp.txt";
const char* out_fn = "c:/temp/out.txt";
string old_str{ "2002" };
string new_str{ "2003" };
// read, rename, write
{
ifstream in{ in_fn };
if (!in)
return -1; // could not open
ofstream tmp{ tmp_fn };
if (!tmp)
return -2; // could not open
string line;
while (getline(in, line))
{
replace(line, old_str, new_str);
tmp << line << endl;
}
} // in & tmp are closed here
// this should be done in one step
{
remove(bak_fn);
rename(in_fn, bak_fn);
remove(out_fn);
rename(tmp_fn, in_fn);
remove(tmp_fn);
}
return 0;
}
One possible way:
Close the file after you read it into "line" variable, then:
std::replace(0, line.length(), "2002", "2003")
Then overwrite the old file.
Note that std::replace is different from string::replace!!
The header is supposed to be <fstream> rather than <stream>
you can't read and write to a file simultaneously so I have closed the file after reading before reopening the file for writing.
instead of updating text inside the file, your line can be updated and then written to file.
#include <iostream>
#include <fstream>
#include <string.h>
#include <string>
using namespace std;
int main(){
string srch;
string line, line2;
fstream Myfile;
string word, replacement, name;
int counter;
Myfile.open("Patientlist.txt", ios::in);
cout << "\nEnter your Name: ";
cin.ignore();
getline(cin, srch);
if(Myfile.is_open())
{
while(getline(Myfile, line)){
if (line.find(srch) != string::npos){
cout << "\nYour details are: \n" << line << endl << "What do you want to change? *type it's word and then type the replacement!*" << endl;
cin >> word >> replacement;
int index = line.find(word);
if (index != string::npos){
Myfile.close();
Myfile.open("Patientlist.txt", ios::out);
line.replace(index, word.length(), replacement);
Myfile.write(line.data(), line.size());
Myfile.close();
}
}
// i want to change in here
}
}else
{
cout << "\nSearch Failed... Patient not found!" << endl;
}
}

How would I go about storing words from a plain text file to an array using C++?

I've been tasked with writing a C++ program that opens a text file, determines the length of each word, then produces output stating how many times a particular word length occurs.
I've figured how to open and read the contents of the file.
How would I take each word and store them in an array?
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
void getFile(string);
void getFile(string filename)
{
string array[2];
short loop = 0;
string line;
ifstream myfile (filename);
if (myfile.is_open())
{
while (!myfile.eof() )
{
getline (myfile,line);
array[loop] = line;
cout << array[loop] << endl;
loop++;
}
myfile.close();
}
else{
cout << "can't open the file";
system("PAUSE");
}
}
int main(){
string fileName;
while (true){
cout << "\nEnter the name of a file: ";
getline(cin, fileName);
if (fileName == ""){
cout << "Invaled file name, enter another!!!"<<endl;
main();
}
else{
getFile(fileName);
}
}
return 0;
}
You do not store words in an array.
You only need to store the word lengths and how often each of them occurred.
If you have a guaranteed and low maximum word length you can even simplify by using an array where the length of the current word is used as an index. Init all entries with 0. Then count entries up when the corresponding word length occurs.

Infinite loop in C++ why?

Im sorry about posting a super long code, but when I run this code all I see is this-
Heap size: 1638652
Getting int:
Getting int:
Getting int:
Getting int:
Getting int:
Heap size: 1638653
and it keeps going in a loop with the heapsize being incremented by one.
#include <iostream>
#include <fstream>
#include <algorithm>
#include <vector>
#include <exception>
#ifndef WX_REPORT_H
#define WX_REPORT_H
#include <string>
#include <sstream>
using std::string;
using std::stringstream;
typedef struct WX_REPORT
{
string unitType;
string stationName;
string time;
string gpsLoc;
int pressure;
int windSpeed;
int temperature;
int humidity;
int windDirection;
string toString()
{
stringstream str;
str << stationName << ": " << time << "\t" << gpsLoc << "\n";
str << pressure << "\n" << windSpeed << "\n" << temperature << "\n";
str << humidity << "\n" << windDirection;
return str.str();
}
}
WXReport;
#endif
/*
* Reports must be in the following format:
* M or I // Metric or imperial units
*/
using namespace std;
vector<WXReport*> heap;
bool compTime(const WXReport* a, const WXReport* b) {
if(a->time < b->time) { // timing
return false;
} else {
return true; // commands to return true
}
}
void heapAdd(WXReport* wx) {
heap.push_back(wx);
push_heap(heap.begin(), heap.end());
}
WXReport* heapPop() { // header popup
pop_heap(heap.begin(), heap.end());
WXReport* rep = heap.back();
heap.pop_back();
return rep;
}
void getInt(istream &input, int &i) {
string temp;
input>>temp;
cout<<"Getting int: "<<temp<<endl;
i = atoi(temp.c_str());
}
void readInFile(string filename) {
ifstream input(filename);
WXReport *report;
while(!input.eof()) {
report = new WXReport();
getline(input, report->unitType);
getline(input, report->stationName);
getline(input, report->time);
getline(input, report->gpsLoc);
getInt(input, report->pressure);
getInt(input, report->windSpeed);
getInt(input, report->temperature);
getInt(input, report->humidity);
getInt(input, report->windDirection);
heapAdd(report);
cout<<"Heap size: "<<heap.size()<<endl;
}
}
int menu() {
cout<<"\n\nPlease select one: "<<endl;
cout<<"1) Read in another file"<<endl;
cout<<"2) Display the fastest wind speed"<<endl;
cout<<"3) Display weather stations by name"<<endl;
cout<<"4) Display all weather reports"<<endl;
cout<<"5) Remove a weather report"<<endl;
cout<<"6) Write weather reports to file"<<endl;
cout<<"0) Exit"<<endl;
int choice;
cin>>choice;
return choice;
}
void printAllReports() {
cout<<"Printing all reports"<<endl;
for(WXReport* rep: heap) {
cout<<rep->toString()<<endl;
}
cout<<"Done printing reports"<<endl;
}
int main(int argc, char* argv[]) {
string filename = "report.txt";
readInFile(filename);
int choice = menu();
while(choice != 0) {
switch(choice) {
case 1:
cout<<"What file would you like to read in?"<<endl;
cin>>filename;
readInFile(filename);
break;
case 2:
cout<<"Has not been implemented"<<endl;
break;
case 3:
cout<<"Has not been implemented"<<endl;
break;
case 4:
printAllReports();
break;
case 5:
cout<<"Has not been implemented"<<endl;
break;
case 6:
cout<<"Has not been implemented"<<endl;
break;
default:
cout<<"Invalid choice, please try again."<<endl;
}
choice = menu();
}
cout<<"Thank you!"<<endl;
return 0;
}
Important part. If you read nothing else, read this: Always check the error codes and return values.
After ifstream input(filename); you have no idea if the file opened. Testing with input.is_open() gets past that.
If the file isn't open, all those calls to getline fail as does eof(). File not open, can't read end of file and can't exit loop. Even if the the file is open, if you don't check the output of getline, how do you know you read a line?
One of the fun parts of streams is if you test the stream, it tells you if it is in a bad state, so you can write code that looks like
if (getline(...) && getline(...) && ...)
So you don't have to make a massive block of if-else-if or a sea of nested ifs. First bad read and you are out.
The problem with if eof() is covered in the comments to the question. The basic is you don't know if you got the end of the file until you start reading. Also, what happen if you hit the end of the file in the middle of a bunch of reads?
So read a line. If it's good, read the next line, etc... until done.
getInt isn't necessary.
int val;
input >> val;
loads an integer into val, if the stream can be parsed into an int. If it can't, input is marked bad and you can check why. Could be unparsable. Could be end of file.
int val;
if (input >> val)
{
//do stuff
}
else
{
//no int here. Do other stuff
}
Just like above, you can chain the instructions and get
if (input >> val >> anotherval >> ...)

How to uppercase all first-letter-characters of sentences after specified delimiter in a text file?

Just as the title says, I have text file that has virtually no uppercase letters in it, so all of the sentences don't look proper without the first letter capitalized. Here's my code so far:
//This program reads an article in a text file, and changes all of the
//first-letter-of-sentence-characters to uppercase after a period and space.
#include <iostream>
#include <fstream>
#include <string>
#include <cctype>//for toupper
using namespace std;
int main()
{
//Variable needed to read file:
string str;
string input = str.find('.');
//Open the file:
fstream dataFile("eBook.txt", ios::in);
if (!dataFile)
{
cout << "Error opening file.\n";
return 0;
}
//Read lines terminated by '. ' sign, and then output:
getline(dataFile, input, '. ');//error: no instance of overloaded function "getline"
//matches the argument list
//argument types are:(std::fstream, std::string, int)
while (!dataFile.fail())
{
cout << input << endl;
getline(dataFile, input);
}
//Close the file:
dataFile.close();
return 0;
}
.
NOTE: I know there is no toupper keyword in my code yet. I don't know where to set it yet.
Instead of this
getline(dataFile, input, '. ');
while (!dataFile.fail())
{
cout << input << endl;
getline(dataFile, input);
}
You can change it to
while(getline(dataFile, line, '.'))
{
for(auto &i : line )
{
if(!isspace(i))
{
i = toupper(i);
break;
}
}
outFile<<line<<".";
}
PS: I would prefer using RegEx for this kind of problems.

Compare variable with each line from a txt file

I have to compare each line of a txt file with a user input variable.
If the userinput word exists within the txt file, it should prompt the user "The word exists." and if it does not, than exit the program.
This is what the text file looks like:
hello
hey
wow
your
Here is my code:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main() {
ifstream file("words.txt");
string content;
string userinput;
while(file >> content) {
cout << content << endl; // gets all the lines from the txt file
while(userinput != "exit") {
// asks user for input
cin >> userinput;
// compares two inputs
if (userinput == content)
{
cout << "The word exists." << endl;
} else {
break;
}
if (userinput == "exit") {
break;
}
}
}
return 0;
}
Its not working for me. I am able to return all the words from the txt file but not able to compare the userinput text with the txt lines from the txt file. Any help would be great. Thanks!
Updated code:
while(iFile >> content) {
while(userinput != "exit") {
// asks user for input
cin >> userinput;
// compares two inputs
if (content.find(userinput) != std::string::npos)
{
cout << "The word exists." << endl;
} else {
break;
}
if (userinput == "exit") {
break;
}
}
}
P.S: I am pretty new to c++. A student
#include <string>
#include <iostream>
#include <fstream>
#include <unordered_set>
using namespace std;
int main()
{
fstream file("wy.txt");
string line;
unordered_set<string> res;
while(file>>line)
{
res.insert(line);
}
do
{
cout<<"Please input the word: "<<endl;
string str;
cin>>str;
if (res.find(str) != res.end())
cout << "The word exists." << endl;
else
break;
} while (true);
}
This code can work fine.
You are running a loop over each line-token in the file, in which you ask the user for guesses until he gives up for each? Nice one, but not what you said.
What you want to do instead:
Read the file, parsing it into word-tokens which you save in an std::unordered_set.
Then ask the user which word shall be matched.
Ask the std::unordered_map to divulge its secrets.
Try it.
When you are writing:
// compares two inputs
if (userinput == content)
You are indeed checking if the user has entered the exact text in content. What you want is checking if userinput is contained in content:
// check if the userinput is found in the text
if(content.find(userinput) != std::string::npos)
You need also to read the complete file. Right now you are reading from the input file each time you are asking an input from the user.
#include <iostream>
#include <fstream>
#include <memory>
#include <sstream>
#include <sys/types.h>
#include <sys/stat.h>
inline static bool fileExists(const std::string& name) {
struct stat buffer;
return (stat (name.c_str(), &buffer) == 0);
}
/// Read the file content and return as a string
static std::string readFile(const std::string &filename)
{
std::ifstream t(filename);
std::stringstream buffer;
buffer << t.rdbuf();
return buffer.str();
}
int main() {
std::string filename("words.txt");
if(!fileExists(filename))
// print error
return -1;
string content = readFile(filename);
string userinput;
... // handle userinput from now
Note that this is inefficient. Since you text is always the same and you are repeating searches, it could be preprocessed. There are multiple data structure that can help. For instance you could have a hash map and populate it with each line as keys.