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 :
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
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;
}
The code that you found somewhere is really bad. You should not use it. Let me explain you why.
Most important, it does not fulfill any of your requirments. So, it is completely wrong for your purpose
There are design-, syntax- and semantic errors. It does not even compile on my machine
Examples: Do not use using namespace std; always use fully qualified names like std::string
Type of vearibe offset should be size_t. You compare it later to string::npos. So, type is wrong
The constructor of std::ifstream can open the file for you. So the call to open is not necessary
MyFile is not a class name. it should start with a lowercase character
Using is_open is not necessary. The bool operator for the iostreams is overloaded. So, you can simply write if (myFile)
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))
Explicit call to close is not necessary. The destructor of the stream will automatically close the file for you
Function should haveonly one exit point. There are 2 return statements.
cout << "Not found" << endl; can be replaced by std::cout << "Not found\n". But better would be to mention, what has been "not found"
Do not use char* for strings. Always use std::string instead.
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;
}
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
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.
Related
I'm trying to open a C++ .txt file as shown in my code below. This is part of a larger program that I'm working on where I write the contents of one file into another so that it contains the same information as the original but I am required to provide user-input. If the user-provides a .txt file that is not the one we are using, I have to produce an error message and prompt them to re-enter an input until they input the correct one (test.txt):
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{
/* Refers to test.txt */
ofstream mainfile;
std::string filename;
std::cout << "Please enter the name of your data file: ";
std::cin >> filename;
mainfile.open(filename.c_str());
mainfile << "test.txt";
if(!mainfile) {
std::cout << "I'm sorry, I could not open '" << filename << "'." << std::endl;
std::cout << "Please enter another name: " <<
std::endl;
std::cin >> filename;
} else {
std::cout << "File '" << filename << "' opened successfully!" << std::endl;
}
return 0;
}
My current issue is that the program is terminating too early, even when I input incorrect inputs such as jaguar.txt or flowers.txt, anything that isn't "test.txt". In fact, when I input just about any .txt file name it will output saying that it opened successfully.
It seems that what you want to do is open up 2 different files, where one is used as the file to copy from (test.txt), and the other is the file to copy to (jaguar.txt). Instead of checking if test.txt exists with std::ofstream, you should instead use std::ifstream.
Using ifstream, if the file does not exist, your code will work properly. Instead, because you are currently using ofstream, the file will open correctly, because you're essentially telling it to make the file for you.
So basically, where you have used ofstream mainfile, instead it should be:
ifstream mainfile;
Later in the code, you can prompt the user for the file to copy to (i.e. jaguar.txt), and this will be the one where you output data using ofstream.
Use ifstream to read from a file, and ofstream to write to a file.
To check whether the source file exists, test the corresponding ifstream after trying to open it:
ifstream mainfile; // ifstream stands for "input file stream"
std::cout << "Please enter the name of your data file: ";
std::cin >> filename;
mainfile.open(filename);
while (!mainfile) { // asking endlessly, until the user inputs a good file
std::cout << "I'm sorry, I could not open '" << filename << "'." << std::endl;
std::cout << "Please enter another name: " <<
std::endl;
std::cin >> filename;
mainfile.open(filename);
}
std::cout << "File '" << filename << "' opened successfully!" << std::endl;
By the way, in the error message "open" is programmer's jargon. It's a general word which includes both reading and writing. If your application copies stuff from one file to the other, the user may get confused: is there a problem with input or output? You might want to say "read" instead of "open", even though technically you didn't read anything yet. That would make a clearer error message.
If you want to copy one file to another, use one of the methods described in a dedicated question.
I've been trying to write a program to open a file in both read and write mode:
#include <fstream>
#include <iostream>
using namespace std;
int main(){
fstream obj;
obj.open("hello.txt",ios::in|ios::out);
if (!obj){
cout << "File not opened" <<endl;
return 1;
}
obj << "Hi How are you" ;
char c;
while (!obj.eof()){
obj.get(c);
cout << c;
}
obj.close();
return 0;
}
When I compile this program on Visual Studio Code on Windows, though the text "Hi how are you" is printed in the file, the contents of the file are not printed on my screen. Can someone tell me what might be the problem?
Resetting the position indicator with seekp to 0 helps, because both output and input indicators are set to the end of file after write operation (you can read them with tellp tellg).
obj << "Hi How are you" ;
obj.seekp(0);
char c;
while (!obj.eof()){
obj.get(c);
cout << c;
}
Considering avoiding using obj.eof(), you can e.g. read your file line by line:
std::string line;
std::getline(obj, line);
std::cout << line << std::endl;
or in the loop:
while (std::getline(obj, line)) // here std::basic_ios<CharT,Traits>::operator bool is used to check if operation succeeded
{
std::cout << line << std::endl;
}
You got two problems there: buffering and seek position.
Buffering:
When you write the text with obj << "Hi How are you, you just write it into the buffer and the text gets written into the file after flushing the buffer. You can adjust which buffer type you want to use. The easiest way is to write std::endl after your text if you use line buffering.
A better explaination is already here
Seek Position:
You are reading from the last position in your file. You have to manually change the read position to the first character in the file, then you are done.
Note: I am using the C++11 standard, so I don't see why this isn't working with or without c_str() appended.
I have the following code:
// open streams
ifstream in(input);
ofstream out(output);
// get which file to open
in.ignore(INT_MAX, ':'); // we don't need the beginning part
in.ignore(); // remove trailing whitespace
string fileLocation;
getline(in, fileLocation);
out << "Loading: " << fileLocation << endl;
cout << "Loading: " << fileLocation << endl;
// now that we know where the file is, load it:
ifstream file(fileLocation);
which reads from a file that looks vaguely like this
File: file.txt
(Subcommands below)
I know that I am pulling the correct filename because of the terminal output.
Anyway, I noticed that the stream wasn't opening properly, so I added this conditional to check:
if ( !file )
{
cout << "File wasn't loaded properly." << endl;
}
And sure enough, I see that message when running the program.
My question is this: how come, when I hard-code the file location, e.g. ifstream file("file.txt") it opens up no problem? How do I get this working properly?
I have some code here
https://github.com/Fallauthy/Projects/blob/master/cPlusPlusProjects/bazaPracownikow/bazaPracownikow/bazaPracownikow/main.cpp
And I have no idea how to show contents in my file. I mean i know how, but it doesn't show same I Have in file (in link). It show in next line. This code is responsible to load file
while (!baseFile.eof()) {
//wczytaj zawartosc pliku do zmiennej
std::string buffer;
baseFile >> buffer;
//wypisz
loadLineFromBase += buffer;
loadLineFromBase += " \n";
}
std::cout << loadLineFromBase << std::endl;
Unless I see all your code all I can do for you is give you a sample in return, I don't know what you're trying to do but it seems in this case you're looking for this.
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{
string Display = "";
ofstream FileOut;
ifstream FileInput;
FileOut.open("C:\\Example.txt");
FileOut << "This is some example text that will be written to the file!";
FileOut.close();
FileInput.open("C:\\Example.txt");
if (!FileInput)
{
cout << "Error File not Found: " << endl;
return 1;
}
while (!FileInput.eof())
{
getline(FileInput, Display);
}
FileInput.close();
cout << Display << endl;
return 0;
}
Simply put if you're currently working wit ha text document
use getline()
When you use getline() it takes two arguments the first will be in this case your ifstream object, as in what you're using to open the file. The second will be the string you're using to store the contents in.
Using the method I outlined above you'll be able to read the entire file contents.
And please next time as it was said above outline your problem more in depth and if you provide us with all of your code we may better assist you!
Your snippet of code automatically add a newline to every string read from the input file, even if originally those were words separeted by spaces. Probably you want to keep the structure of the original file, so it's better to read one line at a time and, unless you need it for some other uses, print it out in the same loop.
std::string buffer;
// read every line of baseFile till EOF
while ( std::getline(baseFile, buffer) ) {
std::cout << buffer << '\n';
}
I'm trying to write up a program that will display the contents of a text file to the screen for a user. Specifically, the text file will be a list of names that the program will read and display each name to the user individually. The user will then either like the name and keep it or dislike the name and remove it.
My dilemma is: if the user elects to keep the name, the program will need to go from reading the file to "writing" (deleting the name) the file and then back to reading the file again! I found the following relevant code on http://www.tutorialspoint.com/cplusplus/cpp_files_streams.htm. It shows that one must use .close() to switch from reading to writing, but this seems funky to a newbie like me. Is there a better way to do it or is the code below just fine?
#include <fstream>
#include <iostream>
using namespace std;
int main ()
{
char data[100];
// open a file in write mode.
ofstream outfile;
outfile.open("afile.dat");
cout << "Writing to the file" << endl;
cout << "Enter your name: ";
cin.getline(data, 100);
// write inputted data into the file.
outfile << data << endl;
cout << "Enter your age: ";
cin >> data;
cin.ignore();
// again write inputted data into the file.
outfile << data << endl;
// close the opened file.
outfile.close();
This is where the file goes from write mode to read mode.
// open a file in read mode.
ifstream infile;
infile.open("afile.dat");
cout << "Reading from the file" << endl;
infile >> data;
// write the data at the screen.
cout << data << endl;
// again read the data from the file and display it.
infile >> data;
cout << data << endl;
// close the opened file.
infile.close();
return 0;
}
Also, I'm having a hard time finding how to read and modify individual characters in the file. I need to do this too, as the file needs to follow a specific pattern, with five names per line and one space between each name (newline at end of fifth name, obviously). Help with this would be appreciated.
Changing things mid-file is complicated.
What I would do is either create a temporary file, write the kept names to that file and replace the original file with this temporary file, (or just store the kept names in a vector and rewrite the file)
try
std::fstream ff("io.txt", std::fstream::in | std::fstream::out);
and fstream::read, fstream::write, fstream::seekg
If the file is small then load it into memory.
Otherwise use fopen with "a+" or "r+" mode and fseek.