Methods for opening a specific file inside the project WITHOUT knowing what the working directory will be - c++

I've had trouble with this issue across many languages, most recently with C++.
The Issue Exemplified
Let's say we're working with C++ and have the following file structure for a project:
("Project" main folder with three [modules, data, etc] subfolders)
Now say:
Our maincode.cpp is in the Project folder
moduleA.cpp is in modules folder
data.txt is in data folder
moduleA.cpp wants to read data.txt
So the way I'd currently do it would be to assume maincode.cpp gets compiled & executed inside the Project folder, and so hardcode the path data/data.txt in moduleA.cpp to do the reading (say I used fstream fs("data/data.txt") to do so).
But what if the code was, for some reason, executed inside etc folder?
Is there a way around this?
The Questions
Is this a valid question? Or am I missing something with the wd (working directory) concept fundamentals?
Are there any methods for working around absolute paths so as to solve this issue in C++?
Are there any universal methods for doing the same with any language?
If there are no reasonable methods, how would you approach this issue?
Please leave a comment if I missed any important details with the problem's illustration!

At some point the program has to make an assumption where the file(s) are. Either by getting it from user input or a relative path with the presumed filename. As already said in the comments, C++ recently got std::filesystem added in C++17 which can help you making cross-platform code that interacts with the hosts' filesystem.
That being said, every program, big or small, has to make certain assumptions at some point, deleting or moving certain files is problematic for any program in case the program requires them to be at a certain location under a certain name. This is not solvable other than presenting the user with an error message etc.

As #Hatted Rooster said, it's not generally solvable for some arbitrary file without making some assumptions, however there are frameworks that allow you to "store" some files in the resources embedded into the executable (or otherwise). Those frameworks would usually allow your to handle such files in a opaque way, without the need to rely on a current working dir or relative paths.
For example, see the Qt Resource System.

Your program can deduce the path from argv[0] in the main call, if you know that it is always relative to your executable or you use an absolute path like "C:\myProgram\data\data.txt".
The second approach works in every language.

Related

Where to store resources for C++ program on linux

This question says the best place to store settings in linux is in ~/.config/appname
The program I'm writing needs to use a 99MB .dat file for recognizing facial landmarks, embedding it in the binary doesn't seem like a good idea.
Is there some default place to store resources on linux? currently it's just in the directory next to the executable, but this requires that the program is run with the current directory being the directory it's located in.
What's the best way to deal with resources like this on linux? (that could potentially be cross platform with at least OSX)
You should take a look at the Filesystem Hierarchy Standards. Depending on the data (will it change, is it constant across all installations, etc) the path where it gets placed will change based on the standards.
In general:
/usr/lib/program: includes object files, libraries, and internal binaries for an application
/usr/share/program: for all read-only architecture independent data files
/var/lib/program: holds state information pertaining to an application or the system
Those seem like pretty good places to start, and you can check the documentation to see if your app falls into one of those categories.
If the file is specific to the user running the app, it should be in a subdir of ~/ but AFAIK there's no standard, and the best choice depends much on the file type/usage. If it should be visible to the user via GUI, you could use ~/Desktop or ~/Downloads. If it's temporary, you can use ~/tmp or ~/var/tmp.
If it's not specific, you should place it in a subdir of /var. Again, the exact subdir may depend on its kind and other factors.

Is it a good idea to include a large text variable in compiled code?

I am writing a program that produces a formatted file for the user, but it's not only producing the formatted file, it does more.
I want to distribute a single binary to the end user and when the user runs the program, it will generate the xml file for the user with appropriate data.
In order to achieve this, I want to give the file contents to a char array variable that is compiled in code. When the user runs the program, I will write out the char file to generate an xml file for the user.
char* buffers = "a xml format file contents, \
this represent many block text \
from a file,...";
I have two questions.
Q1. Do you have any other ideas for how to compile my file contents into binary, i.e, distribute as one binary file.
Q2. Is this even a good idea as I described above?
What you describe is by far the norm for C/C++. For large amounts of text data, or for arbitrary binary data (or indeed any data you can store in a file - e.g. zip file) you can write the data to a file, link it into your program directly.
An example may be found on sites like this one
I'll recommend using another file to contain data other than putting data into the binary, unless you have your own reasons. I don't know other portable ways to put strings into binary file, but your solution seems OK.
However, note that using \ at the end of line to form strings of multiple lines, the indentation should be taken care of, because they are concatenated from the begging of the next lineļ¼š
char* buffers = "a xml format file contents, \
this represent many block text \
from a file,...";
Or you can use another form:
char *buffers =
"a xml format file contents,"
"this represent many block text"
"from a file,...";
Probably, my answer provides much redundant information for topic-starter, but here are what I'm aware of:
Embedding in source code: plain C/C++ solution it is a bad idea because each time you will want to change your content, you will need:
recompile
relink
It can be acceptable only your content changes very rarely or never of if build time is not an issue (if you app is small).
Embedding in binary: Few little more flexible solutions of embedding content in executables exists, but none of them cross-platform (you've not stated your target platform):
Windows: resource files. With most IDEs it is very simple
Linux: objcopy.
MacOS: Application Bundles. Even more simple than on Windows.
You will not need recompile C++ file(s), only re-link.
Application virtualization: there are special utilities that wraps all your application resources into single executable, that runs it similar to as on virtual machine.
I'm only aware of such utilities for Windows (ThinApp, BoxedApp), but there are probably such things for other OSes too, or even cross-platform ones.
Consider distributing your application in some form of installer: when starting installer it creates all resources and unpack executable. It is similar to generating whole stuff by main executable. This can be large and complex package or even simple self-extracting archive.
Of course choice, depends on what kind of application you are creating, who are your target auditory, how you will ship package to end-users etc. If it is a game and you targeting children its not the same as Unix console utility for C++ coders =)
It depends. If you are doing some small unix style utility with no perspective on internatialization, then it's probably fine. You don't want to bloat a distributive with a file no one would ever touch anyways.
But in general it is a bad practice, because eventually someone might want to modify this data and he or she would have to rebuild the whole thing just to fix a typo or anything.
The decision is really up to you.
If you just want to keep your distributive in one piece, you might also find this thread interesting: Store data in executable
Why don't you distribute your application with an additional configuration file? e.g. package your application executable and config file together.
If you do want to make it into a single file, try embed your config file into the executable one as resources.
I see it more of an OS than C/C++ issue. You can add the text to the resource part of your binary/program. In Windows programs HTML, graphics and even movie files are often compiled into resources that make part of the final binary.
That is handy for possible future translation into another language, plus you can modify resource part of the binary without recompiling the code.

Hiding application resources

I'm making a simple game with SFML 1.6 in C++. Of course, I have a lot of picture, level, and data files. Problem is, I don't want these files visible. Right now they're just plain picture files in a res/ subdirectory, and I want to either conceal them or encrypt them. Is it possible to put the raw data from the files into a resource file or something? Any solution is okay to me, I just don't want the files exposed to the user.
EDIT
Cross platform solutions best, but if they don't exist, that's okay, I'm working on windows. But I don't really want to use a library if it's not needed.
Most environments come with a resource compiler that converts images/icons/etc into string data and includes them in the source.
Another common technique is to copy them into the end of the final .exe as the last part of the build process. Then at run time, open the .exe as a file and read the data from some determined offset, see Embedding a filesystem in an executable?
The ideal way for this is to make your own archive format, which would contain all of your files' data along with some extra info needed to split files distinctly within it.

Is there any method to know whether a directory contain a sub directory?

I am woking in c++.
Is there any method to know whether a directory contain a sub directory?
CFileFind seems have to search through total files.
It is time consuming if the only subdirectory is at the end of the list and the there are lots of files.
for example: directory A contains 99995 files and one subdirectory at the end of FindNextFile List. had I try 99995 times, then say: yes, it contains subdirectory?
Raymond Chen from Microsoft has written a post that probably applies here: Computing the size of a directory is more than just adding file sizes. In essence, he explains that information like the size of a dir cannot be stored in the dir's entry, because different users might have different permissions, possibly making some of the files invisible to them. Therefore, the only way to get the size the user should see is to calculate it upon request from the user.
In your case, the answer probably stems from the same reasoning. The list of directories available to your app can only be determined when your app asks for it, as its view of the root directory might be different than another app's, running with different credentials. Why Windows store directories along with files I don't know, but that's a given.
Since Win32 is as close as you'll get to the file system in user mode, I'd avoid any higher level solutions such as .NET, as it might only simplify the interface. A driver might work quicker, but that out of the scope of my knowledge.
If you are using the .Net framework you could use Directory.GetDirectories and check is the size of the array is 0. Do not know how if this will give you speed.
If you have control over the directories you could apply a naming convention so that directories that have sub directories are named one way and directories with out sub directories are named another.
You can try using the boost filesystem library.
A class by name directory_iterator [ declared in boost/filesystem/operations.hpp ] has many functions which can be used for listing files, finding whether the file is a sub-directory ( is_directory -- I guess this is what you are looking for ) etc..
Refer the following link for more information.
link text
It seems you are using MFC [ just saw that you are using CFileFind ], didn't see that earlier.
Sorry, Didn't have much info. You may have to use FindFirstFile/FindNextFile.
Whether this can be done very fast is entirely platform-dependent.
On Win32 you use FindFirstFile/FindNextFile or wrappers on top of those like MFC CFileFind and they list items in some order that can't be forced to list directories first.

Is it possible to have identically named source files in one visual studio c++ project?

I'm working on a static library project for a c++ course I'm taking. The teacher insists that we define only one function per source file, grouping files/functions belonging to the same class in subdirectories for each class. This results in a structure like:
MyClass
\MyClass.cc (constructor)
\functionForMyClass.cc
\anotherFunctionForMyClass.cc
OtherClass
\OtherClass.cc (constructor)
Whether this is good practice or not is something I'd not like to discuss, since I'm simply obliged to organize my project in this manner.
I'm working in visual studio 2008, and somehow got strange link errors when using an identically named function (and thus filename) in two classes. This appears to be caused by the fact that visual studio puts all .obj files (one for each source file) in one intermediate directory, overwriting earlier generated object files when compiling identically named source files.
This could be solved by putting the object files in subdirectories based on the relative path of the input file. Visual studio allows one to configure the names of object files it generates and has macros to use in there, but there appears to be no macro for 'relative path of input file'.
So, is there some way to get this to work? If not, is using one project for each class the best work-around?
You are right, by default all object files are put into the same directory and their filenames are based on the source file name. The only solution I can think of is to change conflicting file's output file path in here:
Project Properties-C/C++-Output Files-Object File Name http://img37.imageshack.us/img37/3695/outputfile.png
PS. It sounds like the lecturer has a crappy (probably written by the lecturer himself) automatic code verifier that imposes this restriction. To get extra marks, offer to rewrite the parser so it works with normal/sane/non-weird projet layout.
Real answer:
Change
C/C++ => Output Files => Output File Name
to
$(IntDir)/%(RelativeDir)/
Every .obj file is going to be created in a sub folder so its not going to overwrite the previous on linking.
I can't think of any way to fudge the project settings to get VStudio to automatically split out the intermediate files into separate folders.
You have a few chances -
Build the class name into each file name. Most IDE's display just the file name in the tab view so if you do have several methods in different classes with the same name, its going to be difficult to tell them apart if the file name does not include the class name along with the method name. Which is really why I think your teachers advice is madness. I have not seen any programming style guide advocating that approach. Additionally it goes directly against the way various tools work - if you use Visual Studio to create a class, it creates one cpp file and one header, and automatically appends each new function to the single cpp file.
You could create a static library per class. When linking in static libs the obj files are all packaged up inside the .lib so conflicts are no longer a problem.
Switch comp-sci courses to one thats not being taught by a nut job. Seriously, this guy is completely out of touch with industry best practices and is trying to impose their own weird ideas on their students: Ideas that are going to have to be unlearnt the moment they leave the teaching environment.
You can also change output file name per file in its properties. Just make sure you use different names.
Can you use the class name in the filename to disambiguate? I'm thinking that you might have
MyClass
\MyClass.cc (constructor)
\function1_MyClass.cc
\function2_MyClass.cc
That would mean that every file would have a unique-enough name to defeat the problem. Is that an acceptable strategy?
You could probably arrange the properties of the project to put the object files into a folder which is below the folder of each source file. Once the project has this property, then every source file should inherit this property. (But if you've done experiments like Igor has suggested, then you may need to go through the properties as reset them back to the parent).
Having looked at the help files, I think you should go to project properties/C C++/Outpuf Files/Object File Name: and enter $(InputDir) (no trailing backslash). Every source file should then inherit this property and your .obj files should be separated.
You may need to do a Clean Solution before you make any changes.
Renaming the object files will work, but it's going to be a pain, and it will slow your compile/link cycle down. I've never figured out why, but it seems to confuse Visual Studio if the object files don't have the default names.
You could prefix the funciton name with the class name; e.g. myclass-ctor.cc, myclass-function1.cc etc.
You could have one .cc file per class which #includes the individual function files. In this case you'll need to prevent the #included files from being compiled seperately (either rename their extension or set Properties->Exclude From Build to 'Yes').
Out of curiosity, where does your teacher want you to put free functions e.g. local helper functions that might normally belong in an anonymous namespace?
If not, is using one project for each class the best work-around?
Not a good idea - apart from the fact that you won't end up with a single static library (without even more jiggery pokery), your link times are likely to increase and it will hide a
lot of pertinent info from the optimizer.
On another note; If the course is actually about C++ not OO programming, do what you need to pass but take your teacher's advice with a pinch of salt.
You don't have to put them in different translation units... why not put each function in a .h and include them all in one .cc per class? That will very likely give better output from the compiler.
I'd be asking why the teacher is insisting on this odd structure, too, the reasoning behind it should be explained. I know you didn't ask that of us, so that's all I'll say.
In Visual Studio 2010, I set
Properties -> C/C++ -> Output Files -> Output File Name
to
V:\%(Directory)$(PlatformName)_$(ConfigurationName)_%(Filename).obj
for OBJ files to end up next to the sources assuming the project lies on drive V (no idea whether there is a macro for it, yet).
By the way: $(InputDir) refers to the solution/project directory and will cause the same problem in another directory.