How to "select" current directory? - c++

I am writing a proportion calculator. At the beginning of the program, it loads a ascii text art picture from a .txt in the same folder.
Here is how I am doing it:
//Read picture
string line;
ifstream myfile("/Users/MYNAME/Desktop/MathScripts/Proportions/Value Finder/picture.txt");
if (myfile.is_open()) {
while (!myfile.eof()) {
getline(myfile, line);
cout << line << endl;
}
myfile.close();
} else cout << "Unable to load picture!!!" << endl;
//Finish reading txt
I heard how if the .txt is in the same folder, that you can just use the name and not have to say the directory. Meaning instead of
/Users/MYNAME/Desktop/MathScripts/Proportions/Value Finder/picture.txt
I could just use "picture.txt". That doesn't work for me, and I want the user to be able to move around the "Value Finder" folder without having to edit any code.
I am on Mac and I am using CodeRunner; anything odd?
Please do not tell me to make sure that picture.txt is in the same folder as my code. It is.

In order to open picture.txt without using a fully qualified path it has to reside in the current working directory. When an IDE launches an application it it sets the current working directory to the same one the application resides in. If picture.txt resides in a different directory than the application you will not be able to open it with just it's name. If you need to get the current working directory you can call getcwd like so.
char temp[MAXPATHLEN];
getcwd(temp, MAXPATHLEN);
If you want to allow the user to specify which directory picture.txt is in you can let them pass an argument on the command line. You can then create a fully qualified path with the supplied directory and the picture filename.
int main(int argc, const char **argv)
{
// Add some logic to see if the user passes a path as an argument
// and grab it. here we just assume it was passed on the command line.
const string user_path = arg[1];
//Read picture
string line;
ifstream myfile(user_path + "/picture.txt");
if (myfile.is_open())
{
while (!myfile.eof()) {
getline(myfile, line);
cout << line << endl;
}
myfile.close();
}
else
{
cout << "Unable to load picture!!!" << endl;
}
//Finish reading txt
return 0;
}
Now you can do something like this:
myapp "/user/USERNAME/Desktop/MathScripts/Proportions/Value Finder"
and it will look in that directory for the picture.txt file. (Quotes are required because there is a space in the pathname).
Note: You can call setcwd() to change the current working directory of the application.

Related

Unable to open file without it's full path in C++

I want to get file's content and print it in console, but the code bellow works only if I use full path and I don't want that, I am using Visual Studio 2022
int main() {
std::ifstream file("folder/file.txt");
std::string content = "";
if (file.is_open()) {
while (file) {
std::string line;
std::getline(file, line);
content += '\n' + line + '\n';
}
}
else {
std::cout << "Failed to open file" << std::endl;
}
std::cout << content << std::endl;
return 0;
}
output: Failed to open file
but if I use full path like: "C:\Users\User\...\folder\file.txt" it will work.
Some of the shorter comments give clues to the problem, but I'll provide a longer answer.
Many IDEs -- including Visual Studio -- do NOT have the current directory as your project area. Instead, the current directory when you run your program is in a build area.
Imagine your project is in C:\Users\You\MyProgram. You put the file there (or in a subdirectory), and when you run your program from the IDE, you expect to find it. And it's not there.
That's because the IDE actually sets the current directory to somewhere else. (I'm not sure where -- I don't use Visual Studio.) If you do this:
cout << std::file_system::current_path() << endl;
it should give you a clue.

ofstream creating file but not writing to it in C++

I am writing an MFC program that has a dialog with an "Export" button that will take all of the data that has been entered into the file and export it to a .txt (at some point I want to change this to a .msg file...but that's a question for another day).
However, when I click the button, it creates the file but doesn't write anything inside the file. For testing, I removed everything except just a simple literal string and even that isn't printing. Here is the current code for that event: The myfile.flush() statement is leftover from when I had a loop that I was trying to print to the file.
void CEHDAHTTimerDlg::OnBnClickedExport()
{
// in this function, we want to export the items to a text file
std::ofstream myfile("TodayTime.txt");
myfile.open("TodayTime.txt");
if (myfile.is_open())
{
myfile << "The average call time is ";
myfile.flush();
myfile.close();
}
else
{
SetDlgItemText(IDC_EXPORT, L"Export Unsuccessful! -- No File");
}
}
Is there anything you all can think of that could be causing this? I've been at it for a few hours trying different things, like utilizing a myfile.write() function instead. I've searched a lot around here, reddit, and google in general trying to find out why this isn't writing.
I appreciate your help.
EDIT:
Okay, calling the myfile constructor the way that I did, by including the file name, went ahead and did what open file would have done
Thanks for your help!
commenting out the redundant "open" solves it.
#include <iostream>
#include <fstream>
int main()
{
// in this function, we want to export the items to a text file
std::ofstream myfile("TodayTime.txt");
// myfile.open("TodayTime.txt");
if (myfile.is_open())
{
myfile << "The average call time is ";
myfile.flush();
myfile.close();
}
else
{
std::cerr << "didn't write" << std::endl;
}
}
I strongly suspect that you're invoking undefined behaviour by opening and already-open stream.
Here is the explanation:
The call to myfile.open("TodayTime.txt"); will fail because the stream is already associated with the file, setting the failbit.
The call to is_open() will succeed, as the file is open.
Then the call to streaming operator << will fail (because of the failbit).
this is because myfile << "The average call time is "; not working
to fix that
std::ofstream myfile;
myfile.open("TodayTime.txt",std::ios:app) //app for appending you can use trunc for
//truncating file
//for flushing content's of existing file use myfile.flush();
if (!data_pack.is_open())
{
std::cerr << "unable to open the file for writing";
}
myfile << "some stuff tho write you can replace the string with variable"
<<std::endl; //for next line
//at last close file
myfile.close();

Append to a File with fstream Instead of Overwriting

I'm trying to create a basic highscore system for a project I'm working on.
The problem I'm having is, although I write the names into my main they just overwrite the previous.
Currently I have this:
void ManagePoint::saveScore(string Name, int Score)
{
ofstream newFile("scorefile.txt");
if(newFile.is_open())
{
newFile << Name << " " << Score;
}
else
{
//You're in trouble now Mr!
}
newFile.close();
}
and for testing I'm adding them like so:
runner->saveScore("Robert", 34322);
runner->saveScore("Paul", 526);
runner->saveScore("Maxim", 34322);
On load display all that will appear is Maxim's score, how can I loop through and save them all, or append all or something?
You need to open the file with the append mode:
ofstream newFile("scorefile.txt", std::ios_base::app);
There are various other modes too.

Attaching text file to Visual Studio project...?

I'm almost done with a homework assignment but I'm having a hell of a time with one aspect of it. The purpose of the program is to read in a text file, and then do analysis. Now, if I'm on my computer, I can put in the full path of the file and it runs fine.
But it won't run ok if my professor tries to run it. I tried prompting the user to input a full path and that didn't work. I tried attaching the text file to the .exe but I don't think I did it right.
Anyone have any advice?
//int bookinput = 0;
//string whichbook;
//ifstream bookread;
//ifstream bookread(whichbook.c_str());
//cout << "Welcome to the book analysis program.\n";
//cout << "Please type in the full path of the book, remembering to double backslashes: ";
//cin >> whichbook;
//
//if(bookinput == 1){
// bookselect = "1984.txt";
//}
//else if(bookinput == 2){
// bookselect = "conneticutYankeeInKingArthursCourt.txt";
//}
//
//bookread.open(bookselect.c_str());
//bookread.open(whichbook.c_str());
bookread.open(whichbook.c_str());
if(bookread.is_open()){
std::cout << "opening book\n\n";
if(bookread.good()){
cout << "opening of book successful :D";
}
while(bookread.good()){ //reads to end of file
string input;
//getline(bookread, input);
bookread >> input;
//only add alphanumerical strings to the word list
if (isAlphaNumerical(input))
{
words.push_back(input);
}
}
}
This is the problem:
cout << "Please type in the full path of the book, remembering to double backslashes: ";
Double-backslashes are only meaningful to the C++ compiler. When you prompt the user for a path, the compiler isn't involved and double backslashes should NOT be used. (and string input cannot use \t to indicate a tab, etc., unless you implement special processing afterward)
You can keep the source file/exe file and text file in the same folder. Inform your professor to copy the entire folder and run it from there.
On another thought, the Prof. should have his own copy of the text file and he should be giving you instructions on how to locate the file within your program.
This bit of code I'm assuming is where the file path is being entered/decided.
.......
cin >> whichbook;
if(bookinput == 1){
bookselect = "1984.txt";
}
else if(bookinput == 2){
bookselect = "conneticutYankeeInKingArthursCourt.txt";
}
//should'nt this be either one line?
bookread.open(bookselect.c_str());
bookread.open(whichbook.c_str());
So if bookinput is 1 or 2, you're trying to open a file without specifying the path? You could keep the two text files in the same path as the executable and then you have to get the path of the executable and use it with the filename, instead, the easier/crappier route would be, you could hardcode it to a known path
Like:
bookselect = "C:\\Temp\\1984.txt";

Reading File in C++

I am unable to figure out why my code is not able to open and read a file. What am i missing?
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main (int argc, char * const argv[])
{
string line;
ifstream myfile ("input_file_1.txt");
if (myfile.is_open())
{
while (!myfile.eof())
{
getline (myfile,line);
cout << line << endl;
}
}
else
{
cout << "Was unable to open the file" << endl;
}
return 0;
}
The file "input_file_1.txt" is int he same directory as my .cpp file and it has read permissions. I even gave gave it 777 permissions and i was unable to read it.
Can anyone tell me what i am doing wrong? I really cannot figure it out....
Try to use full path for the file
The default location to look for the file is where the executable is , not where the source is.
How and where do you execute your program? From a IDE?
Can you run the program from the same directory where you have your text file.
Another possibility is to use an absolute path to the file.
If you don't specify a path, the library will attempt to load the file from the current directory. You need to make sure that this is where the file is.
Also, you might not be able to open the file if it is opened in an exclusive manner by another program. Ensure that it is not still open in another program such as your editor.
Other Problems:
Explicitly testing for EOF is usually wrong.
The last valid read (getline() here) reads up-to but no past the EOF. You then print the line. Then restart the loop. These test for eof() does not fail (as it has not read past the EOF). You then enter the loop body and attempt to read the next line (with getline()) this fails as there are 0 bytes left to read (thus leaving the value of line in an undefined state). You then print out line (undefined value) and a newline character.
while (!myfile.eof())
{
getline (myfile,line);
cout << line << endl;
}
A correct version of a loop reading a file is:
while (getline (myfile,line))
{
cout << line << endl;
}
This works because the getline() returns a reference to a stream. A stream used in a boolean context (like a while condition) tests to see if the stream is in a bad state (ie it test for EOF and other bad situations) and returns an object that can be used correctyl in the context. If the state of the stream is OK then a successful read has happened and the loop is entered (thus allowing you to print the line).
The binary created from your code (including your cpp) is executed somewhere different from your code is, probably a "bin"-folder. You schould put the file into the same folder as your executable.