Can't open file properly in C++ - c++

I'm trying to read each line from a .geom file and save that in a string.
The user shall input the correct (absolute) filepath and then, until now, should get the content of the .geom file printed out on the console.
The problem is that under every circumstance it seems impossible to open the file via my c++ program.
Everytime I check if the file is opened via is_open() it responds with false.
The program, my IDE and the .geom file are all on the same drive and i am currently using windows. The IDE im using is Codeblocks and the executable is build in it.
This is my complete code until now:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
//a function to check if the given file has the .geom extension
bool isGeom(string file){
if(file.substr(file.find_last_of(".") + 1) == "geom") {
return true;
} else {
return false;
}
}
//main func
int main()
{
string filepath, geomInput, line;
cout << "----- GeomView2obj -----" << endl;
cout << "Please enter a valid file path to a .geom file to convert it to an .obj file: \n" << endl;
//get file path by user
getline(cin, filepath);
//declare stream and open file if possible
ifstream geomFile (filepath.c_str());
if(!geomFile.is_open()){
cout << "\nERR: The given file path is invalid or the file does not exist!" << endl;
return 1;
}
if(!isGeom(filepath)){
cout << "\nERR: The given file is not a .geom file!" << endl;
return 1;
}
//read chars from geom file
while(getline(geomFile, line)){
geomInput.append(line + "\n");
}
//print string --- DELETE
cout << geomInput;
geomFile.close();
return 0;
}
I also tried to first declare my ifstream and then opening the file.
I also turned the user input off and entered an absolute path where every folder was seperated with two backslashes \\ instead of one.
I also copied the file to the folder the compiled program lies in and giving the program a relative path to the file as an input, but that also did not help.
Any form of help is much appreciated!

Related

find if the word exist in the text file

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.

Passing relative path to ifstream c++

I am working on dev c++. I am using file stream to open a file which is already placed in a folder. Below is my code.
int main(){
ifstream file; // File stream object
string name; // To hold the file name
//Write the path of the folder in which your file is placed
string path = "C:\\Users\\Faisal\\Desktop\\Programs\\";
string inputLine; // To hold a line of input
int lines = 0; // Line counter
int lineNum = 1; // Line number to display
// Get the file name.
cout << "Enter the file name: ";
getline(cin, name);// Open the file.
string fileToOpen = path + name + ".txt";
file.open(fileToOpen.c_str(),ios::in);// Test for errors.
if (!file){
// There was an error so display an error
// message and end the PROGRAM.
cout << "Error opening " << name << endl;
exit(EXIT_FAILURE);
}
// Read the contents of the file and display
// each line with a line number.
// Get a line from the file.
getline(file, inputLine, '\n');
while (!file.fail()){
// Display the line.
cout << setw(3) << right << lineNum<< ":" << inputLine << endl;
// Update the line DISPLAY COUNTER for the next line.
lineNum++;// Update the total line counter.
lines++;// If we've displayed the 24th line, pause the screen.
if (lines == 24){
cout << "Press ENTER to CONTINUE...";
cin.get();
lines = 0;
}
// Get a line from the file.
getline(file, inputLine, '\n');
}
//Close the file.
file.close();
return 0;
}
My file is in the same folder where my program resides i.e. in my C:\\Users\\Faisal\\Desktop\\Programs\\. However, I want to use a relative path, so whoever runs the program can access the file.
How can I pass the relative path?
Any help would be highly appreciated.
Consider using /tmp directory on unices and System.IO.Path.GetTempPath() on Windows.
How to get temporary folder for current user
If you decide to use current working directory, you need to find current working directory executable cwd which is not at the same place on all platforms.
How do I get the directory that a program is running from?
Check out https://en.cppreference.com/w/cpp/filesystem/current_path also

Ifstream cannot open file with amdinistrator rights

I used this code to try to open and read the file (not empty), but ifstream did not work - it could not open the file: I addded the check on file opening and it showed, that ifstream even did not (could not) open the file.
I gave administrator rights to the program, but ifstream still could not read the file.
I also tried to find a path, where ifstream would read this file, but I did not success, and at last I tried to open file using the absolute path - but result is the same.
The file is situated in the root folder of the program, but I placed it everywhere and nothing changed.
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int main() {
string s;
ifstream file("fix.txt");
if (file)
cout << "SUCCESSFULL OPENING" << endl;
while (getline(file, s)) {
cout << s << endl;
s += "+";
cout << s << endl;
}
file.close();
return 0;
}
You may have access to a more detailed error code by activating exceptions on the stream via
file.exceptions(std::ios_base::failbit);
Then, you get more details by writing
try {
file.open("fix.txt");
}
catch(std::ios_base::failure& f) {
// f.what() contains a message, f.code() returns a std::error_code
}

How to open a file that the user gives in output screen using c++

I want the user to give the file name in output screen,for the file to be opened while running the program .More specifically, if the user gives a file name in output screen, my program should open that file for him. How can i code this using files in c++? Can anyone give an example?
example code:
#include <iostream>
#include <fstream>
int main() {
std::string filename, line;
std::cout << "Input file name: ";
std::cin >> filename;
std::ifstream infile(filename);
if(!infile)
std::cerr << "No such file!" << std::endl;
else {
std::cout << "File contents: " << std::endl;
while(infile >> line)
std::cout << line << std::endl;
}
}
contents of test.txt:
hello
world
how
are
you
program output (on console):
Input file name: test.txt
File contents:
hello
world
how
are
you
the way this works is, you declare two strings - one that will be the filename and the other that will be serve as a temporary buffer for each line in file.
when the user inputs a file name, depending on whether the file exists or not, the program will either output an error, or declare and initialize a file stream infile (this basically opens a stream to your file and allows you to extract [or input] data from the desired file).
once that is done, the program will read the file line by line while(infile >> line) and output the contents of each file to console.

Windows drag and drop problem with console app

I have a program that creates a file and writes to it using ofstream. I need the program to be able to parse command line parameters later on. But for some reason, it does not create a file when I drag-and-drop a file onto the compiled executable, even if the program doesn't involve any command line parameters at all. If the executable is run normally, it works. So I'm left totally confused. Here is the source:
#include <iostream>
#include <fstream>
using namespace std;
int main ()
{
ofstream outfile;
outfile.open("test.txt");
if(outfile.is_open())
{
outfile << "Test";
outfile.close();
}
else cout << "Unable to open file";
return 0;
}
Does anybody have any ideas? I appreciate any help.
You are not using the command line arguments at all. Recode your main() method to look like this:
int main(int argc, char** argv)
{
if (argc != 2)
{
cout << "Usage: blah.exe file" << endl;
return 1;
}
ofstream outfile;
outfile.open(argv[1]);
if(outfile.is_open())
{
outfile << "Test";
outfile.close();
}
else cout << "Unable to open file";
return 0;
}
Be careful what you drop, your code rewrites the file contents.
The following code does what the OP wants:
#include <iostream>
#include <fstream>
using namespace std;
int main ( int argc, char ** argv )
{
cout << argv[1] << endl;
ofstream outfile;
outfile.open("testzzzzzzz.txt");
if(outfile.is_open())
{
outfile << "Testzzzzz";
outfile.close();
cout << "wrote file"<< endl;
}
else cout << "Unable to open file";
string s;
getline( cin, s );
return 0;
}
It allows drag and drop, but doesn't use the dropped file name in the file open. When you drop a file in it, you get the message
"wrote file"
Unfortunately, at the moment I have no idea where it wrote the file - not in the current directory, definitely. Just going to do a search...
Edit: It creates it in your Documents and Settings directory. So to put it in the current directory, you probably need to explicitly prefix it with "./", but I havent't tested this - I leave it as an exercise for the reader :-)
Since you have not specified a path, the file, test.txt, will be saved to the default path. Just bring up a command prompt (i.e. run cmd.exe) and the command prompt will show you the default path. The file should be in this directory.
You can change the default path by editing the HOMEDRIVE & HOMEPATH environment variables.
Also, you should note the other answers. You should be using argc/argv to specify the output file.
you haven't specified a path for "test.txt" so it will try and create that file in the current working directory of the executable. This will be different when the exe is invoked by dropping a file on it than it is when you run the program normally.
Try giving "test.txt" a full path and see if that works.
edit:
To write your output file to the path that contains the exe, you would use
GetModuleFileName(NULL, ...) to the the full path of the exe,
then PathRemoveFileSpec to strip off the exe name, leaving just the exe path then
PathCombine to append test.txt to the exe path