Xcode: Where to put input file? - c++

I'm trying to learn C++ and I'm using Xcode. I have the following main method:
int main()
{
const int SIZE = 256;
Expression* expression;
char paren, comma, line[SIZE];
ifstream fin("input.txt");
while (true)
{
symbolTable.init();
fin.getline(line, SIZE);
if (!fin)
break;
stringstream in(line, ios_base::in);
in >> paren;
cout << line << " ";
expression = SubExpression::parse(in);
in >> comma;
parseAssignments(in);
double result = expression->evaluate();
cout << "Value = " << result << endl;
// catch the exceptions
return 0;
}
}
Where do I put the file "input.txt" so the program can read it?

The filename parameter of ifstream is usually taken as a relative path to the working directory so that's where you should put the file.
If you launch the executable from a file manager, the working directory of the process will most likely be set to the directory the executable is in. In that case the text file should be in the same directory.

All relative paths (on OS X, any path that doesn't start with a slash, "/"), are interpreted relative to a process' working directory.
If you're running from the terminal, it should be in the terminal's current directory (i.e. ls should list it).
If you're running from inside XCode, there is a project setting for which directory should be the working directory.
You set that to wherever your file is, or move the file to wherever that directory is.

Related

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

Can't open file properly in 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!

Can't read in one .dat file to create a second .dat file

Trying to read in one file using a while loop (it's called "Stocks.dat" and the reason I'm using a while-loop is because in the future, X amount of stocks may be appended; the format of the .dat file is listed below) to create a second file "profits.dat" which contains the information of "Stocks.dat" but with new calculation floats. This runs fine, but when I check to see if "profits.dat" exists, there is nothing there. Why am I not getting a "profits.dat" file with all the calculations inside? Thanks so much.
#include<iostream>
#include<fstream>
using namespace std;
int main()
{
char name[40];
int sh;
float pp, cp, pc, cv, pr;
ifstream infile("c:\\Stocks.dat", ios::in);
ofstream outfile("c:\\profits.dat", ios::out);
while (infile.getline(name, 40)) //don't forget the whitespace
{
infile >> sh >> pp >> cp;
pc = sh * pp;
cv = sh * cp;
pr = cv - pc;
outfile << name << endl; //need the endline
outfile << pc << ' ' << cv << ' ' << pr << ' ' << endl; //need the blank spaces
infile.ignore(40, '\n');
}
infile.close();
outfile.close();
return 0;
}
//Stocks.dat information:
//APPLE
//500 20.25 30.75
//MICROSOFT
//250 9.75 12.99
//GOOGLE
//1000 50.10 300.85
It is most likely the problem with permissions. Your ofstream fails to open a file for writing at location C: - writing directly to your system drive requires administrator privileges (I think starting from Windows Vista but I'm not sure).
You may run your program as administrator or place the file (change the path as opening for writing will create a file) in a location where you can write.
EDIT:
Change this
ofstream outfile("c:\\profits.dat", ios::out);
to this
ofstream outfile("c:\\users\\YOUR_USER\\desktop\\profits.dat", ios::out);
or some other location where you can write without administrator privileges. You can find such location by opening notepad and trying to save file. If you can save file in that location your program will create profits.dat there successfully.

appending "../xx.txt" to the relative path does work in C++

I read some topics about relative path, but I've been wandering around them for hours without answer.
The code is like this:
std::string path = "./Debug/";
path.append("../hi.txt/");
std::ifstream inFile(path);
std::string str;
if (inFile.is_open())
{
inFile >> str;
std::cout << str << std::endl;
}
else
{
std::cout << "open failed" << std::endl;
}
This code will output:"open failed".
Any help would be appreciated.
When you put a / at the end of a path, it tells the system to execute it as a directory (i.e. list its contents). Since hi.txt is not a directory, you can't execute it as a directory and therefore it fails (assuming of course you didn't name a directory hi.txt).
To fix it: remove the /:
std::string path = "./Debug/" ;
path.append("../hi.txt") ;

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