New to Xcode can't open files in c++? - c++

I've been using windows in a class I've been taking but I am trying to run a basic code to figure out how to open/close/input/output from files on Xcode and the code I usually use on visual studios isn't working any idea why? thanks!
#include <string>
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
ifstream fin;
ofstream fout;
string input;
fin.open("inputFile.txt");
if(fin.fail())
cout << "File failed to open." << endl;
fin >> input;
fout.open("outputFile.txt");
fout << input;
}

Put your .txt files in the same directory where your main.cpp file is (or anywhere you like).
In Xcode go to Product > Scheme > Edit Scheme > Run (on the left) > Options (middle top)
Down under Options for "Working Directory" check “Use custom working directory” and set it to the directory where you .txt files are located.
To work with the files, you will have to specify just file names, e.g. in_file.open("inputFile.txt"); no path is necessary.

Here's a completely different approach: Have Xcode copy the input file for you.
Select your project in Xcode
Select Build Phases
Click the '+' button to create a new Build Phase
Select New Copy Files Build Phase
Select Products Directory
Click the '+' button to add your file
Click Add Other
Select your input file and click Open
Check the Copy items… checkbox and click Finish
Now every time you build your project, the input file will be copied to the same folder as the executable no matter where it is built. Of course, to see the output file, you'll still need to find the executable in Finder.

The answers don't really explain the problem so I thought I'd do that.
When you pass a relative path like "inputFile.txt" to file APIs, it's treated as relative to the working directory when the program is executed. This is the same as the 'working directory' when you use cmd.exe or Terminal.app or command lines in general. The Unix command pwd ("print working directory") displays the current working directory. On Windows running the command cd with no arguments performs the same function. (On Unix running cd with no arguments will change the working directory to the user's home directory.)
When you run a program from the command line, the command line shell sets the program's working directory. When you run a program from within an IDE, the IDE sets the working directory. Since, unlike on a command line, there's no obvious answer for what the IDE should set as the working directory, Visual Studio and Xcode set the working directory to different locations by default: Visual Studio sets the working directory to $(ProjectDir), the directory containing the Visual Studio project file; Xcode sets the working directory to the build products directory, i.e. the location the executable was written to.
Some possible solutions to your problem are:
Do not use a relative path, and therefore don't depend on the working directory. This isn't much help in making the program more portable, because the absolute paths will also differ between platforms, and so you will still have to 'configure' the program for each platform. In fact using an absolute path is worse, because it means your source code must differ, whereas it would be better to keep that difference confined to each platform's build configuration.
Configure the IDE to use your desired working directory. Visual Studio can be configured by right clicking the project, selecting Configuration Properties > Debugging > Working Directory, and setting the working directory to the desired path (potentially using Visual Studio build variables).
nepete's answer describes how to configure the working directly set by Xcode.
Configure the IDE's build process to copy your data files to an appropriate location. In Visual Studio you would do this in a C++ project by configuring the project's Properties > Configuration Properties > Build Events.
SSteve's answer covers how to configure additional build steps in Xcode.

I'm guessing you have inputFile.txt in the folder that contains your source code. That's not going to work. You need to put it in the folder that contains the generated executable. To find that folder, right-click on your app under Products and select Show In Finder.
This image shows what it looks like for a command line program. It also shows the Finder window that was opened. As you can see, it is a different folder than the one containing the source code.

As suggested by nepete, edit the scheme, but use $PROJECT_DIR as the custom working directory. Helps with moving the project around, or working in two different environments (e.g., home and office).
BTW. $PROJECT_DIR is one of the Xcode Environment Variables, and also helps with passing file names as command line arguments to programs (settable under "Arguments" in the scheme).

I've struggled with the same problem today. I wanted to add C code to my Swift project and my file pointer was always NULL.
Unfortunately, in XCode 9 for iOS app, I couldn't change the working directory. Changing Build phases didn't help me either. After 4+ hours of trial and error, that's what I've come up with finally and it works:
when copying files to XCode, I've chosen "Create groups", but I needed to choose "Create folder references":
I created a new objective-c file (.m) and copied all my C code there.
I left untouched .h files (XCode generated bridging header and my own .h file with public functions declaration). Now my project structure looked like this:
In my dict.m file in place of previous plain c fopen part:
FILE *dic = fopen("dictionary.txt", "r");
I added obj-C code:
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"dictionary" ofType:#"txt"];
FILE *dic = fopen([filePath cStringUsingEncoding: NSUTF8StringEncoding], "r");
And it works now without any problem! It's just amazing!
ps I decided to write this answer in case it will help someone like me and will save them some time. If you know how to change working directory in XCode 9 for iOS, please, leave me a comment - now I am really curious why I can't find it.

Related

Calling MATLAB Engine error: libeng.dll is missing from your computer

I am struggling to call MATLAB from a simple .cpp program despite the many resources online for this problem.
My Objective:
Use Microsoft Visual Studio 2010 Professional 64-bit to build .cpp program that
calls MATLAB Engine for built-in functions and graphs (MATLAB R2013b 64-bit)
What I have done:
In the .cpp file property pages, I have:
1) Changed the platform to Active(x64)
2) Added the following paths to the VC++ Directories
Executable Directories: C:\Program Files\MATLAB\R2013b\bin
Include Directories: C:\Program Files\MATLAB\R2013b\extern\include
Reference Directories: C:\Program Files\MATLAB\R2013b\bin\win64
Library Directories: C:\Program Files\MATLAB\R2013b\extern\lib\win64\microsoft
Path Edits
3) Wrote the following program:
// mEng.cpp : Defines the entry point for the console application.
// libeng.dll is in C:\Program Files\MATLAB\R2013b\bin\win64
#include "stdafx.h"
#include <Engine.h>
#include <matrix.h>
#include <iostream>
#include <string>
#include <cmath>
#pragma comment (lib, "libmat.lib")
#pragma comment (lib, "libmx.lib")
#pragma comment (lib, "libmex.lib")
#pragma comment (lib, "libeng.lib")
#pragma comment (lib, "libut.lib")
using namespace std;
int main()
{
Engine *m_pEngine;
if (!(m_pEngine = engOpen("")))
{
fprintf(stderr, "\nCan't start MATLAB engine\n");
return EXIT_FAILURE;
}
//Now call the MATLAB script through MATLAB Engine
engEvalString(m_pEngine, "script");
cout << "Hit return to continue\n\n";
fgetc(stdin);
//Close the MATLAB Engine
engClose(m_pEngine);
return EXIT_SUCCESS;
}
Errors received:
“The program can’t start because libeng.dll is missing from your computer. Try reinstalling the program to fix this problem.”
I faced the same problem and spent one day to solve it.
So here is my answer.
Actually you overdefine different directories (see the "Path Edits" link).
It is enough to made just these:
Project Properties -> VC++ Directories -> Library Directories. Add here path C:\Program Files\MATLAB\R2016a\bin\win64 (version and path can differ, but the idea is to est path to the same folder of your MATLAB)
Project Properties -> C/C++ -> General -> Additional Include Directories. Add path C:\Program Files\MATLAB\R2016a\extern\include (your path of this folder)
Project Properties -> Linker -> General -> Additional Library Directories. Add path C:\Program Files\MATLAB\R2016a\extern\lib\win64\microsoft
Project Properties -> Linker -> Input -> Additional Dependencies. Add here: libeng.lib; libmx.lib;
And the last and the most important: add the path of MATLAB Engine dll libraries to your Windows. This step solve your problem. We can do it this way: My Computer -> right click: Settings. Opened window System. Left bottom corner: Advanced System Settings
Advanced Tab
In the Environment variables for your user press Create... button and add this one:
Variable name: PATH
Variable value: C:\Program Files\MATLAB\R2016a\bin\win64
This path is reference on where is your libeng.dll located.
Important moment: it can require to restart VS or even restart computer.
Hope it helps some people, who start to work in MATLAB and C++!
Follow my notes here:
https://www.mathworks.com/matlabcentral/answers/100603-how-can-i-compile-a-matlab-engine-application-using-microsoft-visual-studio-9-0-or-10-0
I would like to take this opportunity though to re-format the instructions given there:
To compile a MATLAB engine application in the Microsoft Visual Studio 9.0 (2008) or Microsoft Visual Studio 10.0 (2010) environments, perform the steps outlined below:
Open Microsoft Visual Studio and select
File->New->Project
and then select:
Visual C++ -> General -> Empty Project
Following this, enter the name of the project and its location in the
indicated text areas and click OK.
Note be very careful with this step as it will create the solution folder and
put a project folder in there, so you won't want to set this up, get it all
working and then change the folder as that will break the solution and you'll
have to start all over.
Right-click on the SOURCE FILES folder in the SOLUTION EXPLORER and click
Add -> "New Item..."
Choose "C++ file (.cpp)", enter the name of the file
(as enginedemo.cpp) as you wish. Click OK.
Copy the code from the source file: engwindemo.c, and paste it into this
file enginedemo.cpp. The file engwindemo.c may be obtained from the following
location:
$MATLABROOT/extern/examples/eng_mat
where $MATLABROOT is the MATLAB root directory, and may be determined by
entering the command:
matlabroot
at the MATLAB command prompt.
I'd suggest that at this point you open it in Notepad and if it has some
weird format, fix and save it so it looks like a normal C file when you open
it in Notepad (or gedit or whatever).
This is where things change in Visual Studio and I hope this extends somewhat
transparently to VS Code, Eclipse, or whatever IDE you'd like to use.
So I will re-number the property change section in roman numerals and fix the
order.
Also be sure to hit ENTER and then APPLY after making every change.
Make sure of the change before you go to the next section.
Double-check the spelling and MAKE SURE the directories exist on your
platform.
Go into the Solution Explorer view, Right click on the project name and
select PROPERTIES in the solution explorer to open the project properties.
Once this window has opened, make the following changes:
Go to the Configurations bar at the top of the property page.
You most definitely want to start with this setting.
Pick a configuration, debug or release, or "all configs" if you want the
changes to apply to BOTH debug and release, or you will have to do them all
over again for the other configuration. Which may not be such a bad idea, as
the individual release options are often more "optimized" versions of the
corresponding debug options. Note you can run
into serious trouble changing the property values while switching between
debug and release modes, don't be surprised if the IDE crashes, the solution
database gets corrupt, even the debug won't build and you have
to start all over. Get the debug to work first, back-up the entire solution,
then "clone" the debug settings to release, and then tweak the release
settings one at a time, making sure that the code still builds and runs
between each change.
If compiling to 64-bit Windows, change the target from x86 to x64 & use 64-
bit DLLs and library files.
If this is not in the Configuration options at the very top where it says
"Configuration Manager" (as in VS2015), then follow your IDE instructions...
as mentioned on the following link:
https://www.microsoft.com/en-us/download/details.aspx?id=55984
Under
Configuration Properties ->Debugging
Add the following Target path in the Environment:
(for 32 bit MATLAB)
PATH=$matlabroot\bin\win32
(for 64-bit MATLAB)
PATH=$matlabroot\bin\win64 If you want to use an absolute path instead,
use the following (with a semicolon at the end)
PATH=C:\Program Files\MATLAB\R2013a\bin\win32; (for 32 bit MATLAB)
PATH=C:\Program Files\MATLAB\R2013a\bin\win64; (for 64 bit MATLAB)
(probably can skip the "PATH=" here as it doesn't seem to remain there,
otherwise this is straight from the MATLAB reference )
Under C/C++ General, add the following directory to the field ADDITIONAL
INCLUDE DIRECTORIES:
$MATLABROOT\extern\include
i.e.
c:\Program Files\MATLAB\R2019a\extern\include;
Put a semicolon at the end of every line that you enter that is a path. after
the .lib files in that section also.
Under C/C++ Precompiled Headers, select "Not Using Precompiled Headers".
(in release mode this was set to "yes")
Under Linker General, add the library directory to the field ADDITIONAL
LIBRARY DIRECTORIES:
(For 32-bit Windows)
$MATLABROOT\extern\lib\win32\microsoft
(For 64-bit Windows)
$MATLABROOT\extern\lib\win64\microsoft
i.e.
c:\Program Files\MATLAB\Rxxxxx\extern\lib\win(32|64)\microsoft;
Under Linker Input, add the following library names to the field marked
ADDITIONAL DEPENDENCIES:
(use this string in front of whatever else is in there)
libeng.lib;libmat.lib;libmx.lib;
I don't know if the order really matters, but the original reference listed
them in reverse alphabetical order. "I've heard it both ways".
Ok, now you're done changing the VS project property pages, save the changes
(as you've done all along by clicking "Apply" after each change) and click
Ok. The property pages window will close. At this point your code will build
but still won't call Matlab. Back-up the solution again.
Now change the DOS/WINDOWS ENVIRONMENT PATH STRING.
I would save the solution, close VS, back it up, make the PATH changes and
reopen VS and try to build your program and run it and have it work.
The PATH string must be changed so that the bin\win(32:64) directory is the
first instance related to Matlab on the path.
Go in the "advanced system settings" \ Environment
To do this, check the Windows system path by clicking on Start -> Right click
on Computer -> Properties -> Advanced System Settings -> Environment
variables -> System Variables -> Open "Path" for editing.
and modify the PATH variable as so:
Make sure that the following directory is in the PATH:
(For 32-bit Windows)
$MATLABROOT\bin\win32
(For 64-bit Windows)
$MATLABROOT\bin\win64
It does not have to be the first directory in the path, but it needs to be
the first MATLAB directory in the path
PATH=c:\;....;c:\Program Files\MATLAB\Rxxxxx\bin\win(32/64);
The matlab.exe is in \bin; you might want that on the path also just not
before the \bin\win64 entry...
Note: If the machine has more than one MATLAB installed, the directory for
the target platform must be ahead of any other MATLAB directory (for
instance, when compiling a 64-bit application, the directory in the MATLAB
64-bit installation must be the first one on the PATH).
Also make sure that your target install of
MATLAB is registered as a COM server:
https://www.mathworks.com/help/matlab/ref/regmatlabserver.html
For Matlab 2020a & later, try comserver('query') and comserver('register').
For 2019 & earlier use regmatlabserver() (run Matlab as administrator).
Build and execute the application.
So I include a simple app that should demonstrate the functionality:
#include "stdafx.h"
#include "engine.h"
#include
using namespace std;
int main()
{
Engine *eng;
eng=engOpen(""); // put a breakpoint here
cout << "...now you see it...\n"
engClose(eng); // put a breakpoint here
cout << "...now you don't!\n"
return 0;
}

Visual C++6 looking for text file in the "solution" directory rather than output directory

I have a VC++6 project and I have the following code snippet:
string s;
int i=0, indx;
ifstream myReadFile;
myReadFile.open("chanmap.txt");
For some reason, when I run the program, it is looking for the text file in the "solution"/root/dsw directory rather than the output directory (i.e. Debug folder) This is a legacy project, so I'm sure that some settings were probably mangled here and there. But this IDE is almost as old as me and very foreign. Any help is appreciated.
For both Debug and Release projects, specify same path in project settings Debugging -> Working Directory:
Other than this, ensure you run the program from Windows Explorer (or command propmpt from the same path). You may need to create a shortcut, where you'd specify directory.
Since you are on Windows, you can also use SetCurrentDirectory within your program.

Cant open html resource file using ifstream::open - Visual Studio 2013

I am working on a project which requires me to open an HTML file and use its contents. I added it to Resource files but when I try to open it lie this:
std::ifstream templateFile;
templateFile.open("filename.html", std::ifstream::in);
The operation fails. I checked it by using templateFile.fail().
The above operation works when I provide the full path. The file lies in the project folder along with other files. I tried setting build action to content but still it doesnt work. Please Help.
Output directory, where your executable is compiled and put into differs from the source directory, where you create all your .cpp/.hpp files (I assume there is filename.html file). Local path filename.html is supposed to be local for your executable file, not the source file.
Read more about changing the output directory here: https://msdn.microsoft.com/en-us/library/ms165410.aspx
Under Configuration Properties / Debugging, see what your Working Directory is using the macros dialog box. Move your file into this folder.
Click the button shown in the figure. There, click either Edit or Browse. Browse will take you to the working directory. Edit will expose the link to open the macros box

Visual Studio 2010 run .exe from command line vs run (f5) debug

I am new to c++ and am making a very simple program. All my program does is call a function from the main function, which reads in a text file and returns. To check that I am reading in the file correctly, I am trying to print out the strings I have read in. The print out (cout) works properly when I run from Visual Studio (f5). However, when I run the executable from command line, none of the print outs from my function show up. Only print outs directly in the main function appear. I cannot find a similar question elsewhere. Any help would be appreciated.
When you run a program from within VC++ the current directory is set to the project directory by default, but the application is by default in a different folder.
E.g. the application may be:
D:\Work\MyApp\Debug\MyApp.exe
But the project directory may be:
D:\Work\MyApp\MyApp\
When you start the program from outside of VC++ you need to take steps to make sure the current directory is correct, or that the executable and any data files it refers to are in the same folder.
The default working directory for an IDE-launched project in Visual Studio is the project folder. This is the folder where you project file resides (the .vcproj or .vcprojx file is the project file).
If the data file you are reading is in the same folder, code like this:
std::ifstream inf("datafile.txt");
will succeed because the current working folder and the folder where the data file resides are the same.
However, if you switch to where the executable was written (typically this is the project-dir/Debug or project-dir/Release folders) and run the same executable from a command-shell, the data file will not be found.
To test this is the case. Do the following:
Open a command prompt.
Switch to the project folder where your data file resides.
Run the executable with a specified path: ./Debug/YourProgram.exe, for example.
Note: you can avoid this by having the program take the data file name as an argv[] parameter. Then your program will simply use whatever file you tell it to at launch-time.

How to use SQLite in C++ program using Code::Blocks?

I'm a complete beginner with Code::Blocks and SQLite, and have some basic knowledge with C++. I'm currently using Ubuntu 11.04.
I have downloaded SQLite Amalgamation here. When I extracted the zip file, there are four files inside: shell.c, sqlite3.c, sqlite3.h, and sqlite3ext.h. If I simply add those files to a (for example) a console project, it gives out an error: the .c's of the downloaded sqlite each have their own main function. Removing those from the project, the errors are gone and I can call #include "sqlite3.h". I am trying to follow this, and tried the first two lines of code from here and it gives out an error: undefined reference to sqlite3_open.
I think adding those .h's directly to a console project isn't the right way to use it, though I'm not sure.
How exactly should I use those? What should I do to use those for my C++ program?
Any help is greatly appreciated. :)
EDIT: I also tried to create a .a file of those sqlite files by following this. When I try it, it gives out an error: cannot find -lsqlite.
I got it! Though there was something that I did that caused problems.. I forget to remove the .a file that I added at Project > Build Options > Linker Settings earlier, which caused problems..
Here are the steps I made to add SQLite: (for those that might have the same problems)
Copy the files extracted from the SQLite Amalgamation to the directory of the project.
Add the sqlite files (Project > Add Files) EXCEPT the shell.c (it is the one that causes the multiple function error)
Compile it (Yes, a simple Ctrl+f9).
here are errors: undefined reference to pthread_mutexattr..... These are fixed by going to Project > Build Options > Highlight 'the Project Name' above Debug and Release at the top left corner > Linker settings, and adding "-lpthread" (without quotes) to Other linker options:.
Some more errors are found: undefined reference to dlopen, dlerror..... Add '"-ldl"' just below the '"-lpthread"' added earlier.
DONE :)
I didn't find a complete answer for Windows as a beginner, and at the beginning it is very painful to understand everything. So here's what worked for me.
Download the SQlite Amalgamation file.
Open Code::Blocks -> New Project -> Choose static library
Unzip the file you have downloaded and copy the folder/contents to your new project directory. Add all the files to the project and build the project.
You will find a ProjectName.a file in the bin/Debug or bin/Release directory. Copy that file to your actual SQlite project directory.
Go to Code::Blocks Project->Build options. Select 'Linker Settings' tab and add the path to the .a file. Don't close it yet!!!
In 'Search Directories' tab, select the 'Compiler' tab, add the path to the Amalgamation header files, or copy the header files to your directory (you can add the header files to your project) and in the 'Linker' tab add the path to the .a file
Now Compile!!! Hopefully this will run
That is all, I wish it'll save some searching time for another noob
You will need to compile the sqlite code first, and then just #include "sqlite3.h" into your project where you need it.
UPD:
Try this:
Download this package from sqlite site and extract it somewhere, say, into a folder called "sqlite". Open terminal, and go into this folder. Inside of it, run
./configure
sudo make
sudo make install
and see what happens. It should build itself automatically. Consult the README file that is inside the archive too.