-3

Please can anybody help me? I'm a beginner and I have a hard assignment. I need to write a c++ program that does the following :

  1. Ask the user to enter two text file , the the first one contains a list of words in one column Regardless of their number , second one contains the text file ,like this: //output

    Enter the keywords file: keywords_file.txt
    Enter the text file: text_file.txt
    

2.Search for the keywords from the keywords file in the text file

3.if the keyword exist the output =1 "true", if the keyword doesn't exist output =0 "false" ,like this :

system : 1 //its exist

book : 0 //its doesn't exist

  1. Then output in new text file (ofstream)

I put the words in file each one on its own line because some of them are phrases I don't want to sprit them ,search them as one word , also the test file I want it to stay as complete text not separate words from each other so possibly I cant use "map" & "vector". I already tried them...so possibly I can consider that each word in the words file just a line and read them all , then search for them in the text file

i found this code here in the site but its need modifications , could any body help me ?

 #include <iostream>
#include <fstream>
#include <string>

using namespace std;

bool CheckWord(char* filename, char* search)
 {
   int offset; 
   string line;
  ifstream Myfile;
   Myfile.open (filename);

  if (Myfile.is_open())
   {
      while (!Myfile.eof())
      {
          getline(Myfile,line);
          if ((offset = line.find(search, 0)) != string::npos) 
           {
            cout << "found '" << search << "' in '" << line << "'" << endl;
            Myfile.close();
            return true;
        }
        else
        {
            cout << "Not found" << endl;
        }
      }
      Myfile.close();
 }
 else
    cout << "Unable to open this file." << endl;

  return false;
 }


 int main () 
 {    
    CheckWord("dictionary.txt", "need");    
    return 0;
   }
  • 1
    Hi, you should first attempt modifying the code yourself and then ask if you face some errors. – Aditya Singh Rathore Apr 24 '21 at 21:14
  • I'm sorry i was working in the code with another idea but its changed lately and i don't have time to do it again ,could you help me please ?? – Haneen Shtaya Apr 24 '21 at 21:17
  • Can `search` be a phrase, like `need this`? – Zoso Apr 24 '21 at 21:20
  • 1
    Do you have a specific programming question or a you looking for someone to do your homework? – Thomas Sablik Apr 24 '21 at 21:30
  • It won't be possible to complete your assignments in your C++ class simply by searching the Internet in order to "found this code here in the site". You will need to study the material that was presented in class and/or your textbook, and apply the learned knowledge in order to write your own program. – Sam Varshavchik Apr 24 '21 at 21:31
  • its not like i don't want to do my homework i already tried many ways to solve it and all of them doesn't do what i need – Haneen Shtaya Apr 24 '21 at 22:26
  • Are you gonna to copy-paste same question until someone do your whole homework ? https://stackoverflow.com/questions/67139003/find-a-frequency-of-words-in-text-file – user3124812 Apr 25 '21 at 11:07

2 Answers2

0

The code that you found somewhere is really bad. You should not use it. Let me explain you why.

  1. Most important, it does not fulfill any of your requirments. So, it is completely wrong for your purpose
  2. There are design-, syntax- and semantic errors. It does not even compile on my machine
  3. Examples: Do not use using namespace std; always use fully qualified names like std::string
  4. Type of vearibe offset should be size_t. You compare it later to string::npos. So, type is wrong
  5. The constructor of std::ifstream can open the file for you. So the call to open is not necessary
  6. MyFile is not a class name. it should start with a lowercase character
  7. Using is_open is not necessary. The bool operator for the iostreams is overloaded. So, you can simply write if (myFile)
  8. while (!Myfile.eof()) is a semantic bug. It will not work as you think. Please find many many examples here on SO. Please write instead while (std::getline(myFile, line))
  9. Explicit call to close is not necessary. The destructor of the stream will automatically close the file for you
  10. Function should haveonly one exit point. There are 2 return statements.
  11. cout << "Not found" << endl; can be replaced by std::cout << "Not found\n". But better would be to mention, what has been "not found"
  12. Do not use char* for strings. Always use std::string instead.
  13. Write many many comments and use meaningful variable names

You see. You should not use this code. It is really bad.

Then, next step, before you start any coding, you should anaylyse the requirements and then design a solution

So, obviously, you need to open 2 input files and one output files. If any of this open activities fail, then no need to open any other file. So, Let us do this sequentially. Open, check, if ok, then open next.

Then, because you want to compare words from a list to the contents of a complete text file, we should first and only once read the comlete text file. Then, we will read keyword by keyword and check, if it is in the text file data.

The we seacrh for the keyword and will show the result in the output file and, for debug purposes, also on std::cout.

Since you are new and have maybe restrictions regarding the usage of modern C++ and espcially the usage of the C++ STL, I will use simple C++ code.

Please see the following simple example.

#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>

int main() {

    // Give instructions to the user to enter the file name for the keywords file 
    std::cout << "Please enter the file name for the keywords file:\t ";

    // Read the filename for the keywords file
    std::string keywordFileNname;
    std::cin >> keywordFileNname;

    // Open the keywords file for reading
    std::ifstream keyWordFileStream(keywordFileNname);

    // Check, if that worked and continue only if OK
    if (keyWordFileStream) {

        // Next, we ant to have the text file name. Instruct use to give the filename for the text file
        std::cout << "Please enter the file name for the text file:    \t ";

        // Read the file name of the text file 
        std::string textFileName;
        std::cin >> textFileName;

        // Open the text file for reading
        std::ifstream textFileStream(textFileName);

        // Check, if the text file could be opened and continue only, of OK
        if (textFileStream) {

            // Now, give instructions to the user to open the output file name
            std::cout << "Please enter the file name for the output file:  \t ";

            // Read the filename for the output file
            std::string outputFileName;
            std::cin >> outputFileName;

            // Open the output file stream
            std::ofstream outputFileStream(outputFileName);

            // Check, if the output file could be opened, If OK, continue
            if (outputFileStream) {

                // So, all files are open, we can start to work
                // We will read the complete text file in one string
                // This solution is not very good, but avoids more complex features
                std::string textFileData;
                char oneCHaracter;
                while (textFileStream.get(oneCHaracter)) {
                    textFileData += oneCHaracter;
                }

                // So, now all text file has been read to one string. 
                // Next we will read keyword by keyowrd and search it in the text file
                std::string keyWord;
                while (keyWordFileStream >> keyWord) {

                    int exists = 0;
                    // Check, if the keyword is in the text file data
                    if (textFileData.find(keyWord) != std::string::npos) {
                        // Keyword found
                        exists = 1;
                    }
                    // Write result to output file
                    outputFileStream << std::right << std::setw(50) << keyWord << std::left << " --> " << exists << '\n';

                    // And write some debug output. You may delete this line if not needed
                    std::cout << std::right << std::setw(50) << keyWord << std::left << " --> " << exists << '\n';
                }
            }
            else {
                // output file could not be opened. Show error message
                std::cerr << "\nError: Could not open output file '" << outputFileName << "'\n\n";
            }
        }
        else {
            // text file could not be opened. Show error message
            std::cerr << "\nError: Could not open text file '" << textFileName << "'\n\n";
        }
    }
    else {
        // Keyword file could not be opened. Show error message
        std::cerr << "\nError: Could not open key word file '" << keywordFileNname << "'\n\n";
    }
    return 0;
}

You can see that I always check the result of IO operations. That is very important.

There is of course also a more advanced and more modern C++ solution. To concentrate more on the essential task, I put all the file handling stuff in a separate function.

This example code uses C++17. So you must enable C++17 for your compiler. Please see (one of many possible solutions)

#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>
#include <vector>
#include <iterator>
#include <algorithm>

// In order to concentrate on the essential task, we put the file stream stuff in a separate function
bool getValidStream(std::ifstream& keyFileStream, std::ifstream& textFileStream, std::ofstream& outFileStream) {

    // We are pessimistic and assume an error
    bool result{ false };

    // Give instructions to the user to enter the file name for the keywords file 
    if (std::cout << "Please enter the file name for the keywords file:\t ")

    // Read keyword text filename
    if (std::string keywordFileNname{}; std::cin >> keywordFileNname)

    // Open key word file
    if (keyFileStream.open(keywordFileNname); keyFileStream)

    // Give instructions to the user to enter the file name for the text file 
    if (std::cout << "Please enter the file name for the text file:    \t ")

    // Read text filename
    if (std::string textFileName{}; std::cin >> textFileName)

    // Open text file
    if (textFileStream.open(textFileName); textFileStream)

    // Give instructions to the user to enter the file name for the output file         
    if (std::cout << "Please enter the file name for the output file:  \t ")

    // Read output filename
    if (std::string outFileName{}; std::cin >> outFileName)

    // Open output file 
    if (outFileStream.open(outFileName); outFileStream)
        result = true;

    if (not result)
        std::cerr << "\nError: Problems with files\n\n";

    return result;
}

int main() {
    
    // Define streams to use in our software
    std::ifstream keyWordFileStream{}, textFileStream{};
    std::ofstream outputFileStream{};

    // Get valid streams
    if (getValidStream(keyWordFileStream, textFileStream, outputFileStream)) {

        // Read all keywords into a vector
        std::vector keywords(std::istream_iterator<std::string>(keyWordFileStream),{});

        // Read complete textfile into a string variable
        std::string textData(std::istreambuf_iterator<char>(textFileStream), {});

        // Output result
        std::transform(keywords.begin(), keywords.end(), std::ostream_iterator<std::string>(outputFileStream, "\n"),
            [&](const std::string& key) {return (textData.find(key) != std::string::npos) ? key + ": 1" : key + ": 0"; });
    }
    return 0;
}
Armin Montigny
  • 7,879
  • 3
  • 11
  • 29
  • `Do not use char* for strings. Always use std::string instead`. This shouldn't be a general rule at all. Using `std::string_view`, `const char*` is perfectly fine in many scenarios. – Zoso Apr 25 '21 at 17:40
-1

The code you have shown is almost workable. The core logic of finding the search string in the line read from the file using find is what you would want to do. If you find it, return true. That's certainly one way of going about the problem you describe.

Read on why !Myfile.eof() is bad, fix it.

Remove close() calls since the destructor of std::basic_ifstream release the underlying file resource

enter image description here

You're passing in character literals but your function signature is bool CheckWord(char* , char* ). Fix that source of warning.

Once, you've fixed all this, you should be fine. You have the core logic of finding words in a file. I still don't get why you asked the question when you've got a near working solution. If you're looking for complexity gains etc. you need to explore the data structure to be used, but then that's probably not your intention for this assignment.

Zoso
  • 2,286
  • 1
  • 12
  • 22