Running cmd commands in C++ - c++

I am trying to make a text adventure based on C++. I have made folders which contains the specific files to each path. Suppose I go south from a room, i need to go into a folder named "south". I am having problems here as I don't know how to change directory like "cd .\south" in C++. Please tell me how to change directory in C++.
I tried to use:
system("cd .\\south")
but it does not change directory. I also searched on Google but it gives link to another function called "ShellExecute" which I don't know how to use. Please help (I am a complete beginner).

The system function create a new process for the command. This means that any directory changing will be local to that new process.
You want the _chdir function instead:
_chdir("south");
Alternatively you can use the WIN32 function SetCurrentDirectory.
Note: _chdir is the Windows CRT function name, on POSIX systems (like Linux or OSX) it's chdir (without the leading underscore).

Direction 1:
Simply What you have to do is change the current directory. for this read this article
http://msdn.microsoft.com/en-us/library/windows/desktop/aa363806(v=vs.85).aspx
But if your application is multi threaded. then you need to be careful. because current directory is common for the whole application so other thread may change the applications current directory.
Direction 2:
If you need to do this by executing system command (I don't know weather it is possible). then you can execute multiple system command using && in windows environment.
EG: system("cls && date && pause");

The problem is that each system command will be executed in separated processes, so your cdcommand will work but won't be effective for the next commands.
You could use chdir if you're on a Linux/Unix system or SetCurrentDirectory for Win32 API but i'm not sure whether it's actually what you want to do.

The answer to the specific question you are doing have already being given. However, I wonder why you are trying to change the current directory in order to answer to a command given by the user.
Maybe you are doing it this way because you want to gain knwoledge something specific, however, take into account that the average way to face a text adventure is not to create folders in the computer, but to create the appropriate structures.
You should have classes at least for: Location, Object, Character
You should have vector of locations and objects in order to represent all possible locations and objects in the game.
The playing character should also have a list of objects that he is able to carry with him (thogh you can make that extensible to other characters in the game).
Each location should have a: name, description, and a vector of ten positions for the common exits, such as north, south, east, west, ne, nw, se, sw, up and down. Inside that vector, you could store the number of the Location to go when that exit is chosen.
And finally, you need to parse the input of the player, in order for the game to be able to understand the commands.
This of course, are the minimums of the adventure.
You can use already existing systems, such as Inform, though again I don't know if you are trying to exercise your C++ skills.
Remember you can look for the help of true experts in adventures by visiting the interactive fiction forum:
http://www.intfiction.org/forum/

Related

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

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.

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.

Application using two (human) languages

I have a fully working code, written for Windows, built with Visual Studio.
What I want to do, is to add another language to that software. My idea is to have two flags (one English and one German) in the window corner, and to have the language change when user clicks on one of the flags.
What is the common, and best way to do this kind of thing?
So far, my idea is to create two files, and to store all the strings that software will use in those files. One file would hold all strings in English, and the other file will hold all strings in German.
Then, I believe that, when a click on a flag icon is detected, software would load all the strings in a list, or vector, or something similar, and then, I would just printout whichever string i need with vector.at(i).
Also, how would I save the currently used language on application exit, so the next time the app is started, that language is used?
The most commonly used way is more or less same as your idea. Also, to store currently used language on exit, you can create a configuration file writing the lang at application exit and read it on app start.

Linked directory not found

I have following scenario:
The main software I wrote uses a database created by a simulator. This database is around 10 GB big at the moment, so I want to keep only one copy of that data per system.
Assuming I have following projects:
Main Software using the data, located at /SimData
DLL using the data for debugging, searching for data at /SimData
Debugging tool to parse the image database, searching for the data at /SimData
Since I do not want to have all those programs have their own copy of SimData (not only to decrease place used, but also to ensure that all Simulation data used is always up to date for all programs).
I created for the DLL and Debugging Utility a link named SimData to MainSoftware/SimData, but when opening a file with "SimData\MyFile.data" it cannot find it, only the MainSoftware with the ACTUAL SimData folder can find it.
How can I use the MainSoftware/SimData folder without setting absolute paths?
This is on Windows 7 x64
I agree with Peter about adding the DB location as a configurable parameter. A common place to store that is in the registry.
however, If you want to create links that will be recognized by your software, try hardlinks. . fsutil should do the trick as described here.
You need a way to configure the database location. You could use an INI or other configuration file, or a registry setting, or a command-line input, or an environment variable. Or You could write your program to search a directory hierarchy... for example, if the various modules are usually siblings of each other in your directory tree, you could search for SimData/MyFile.data, ../SimData/MyFile.data, ../../MainSoftware/SimData/Myfile.data, and use the first one found.
Which answer is the "right one" depends on your situation.

Paths to do-file in Stata

Would it be possible, when I launch a do-file to recover the path of the do-file as a variable?
I'm sharing a project with a co-author (via Dropbox). The structure of the folders (data, logs, etc.) is therefore the same on both sides.
But the folders are situated differented on my coauthor's filesystem and mine. It would therefore be helpful for us to write do-file that are agnostic about the path of the folders, etc.
We would like the path to our projects not to be hard-coded.
Thank you!
You can do various things in this territory, including
Passing the name of a directory to a do-file as an argument. For example,
do mydo d:/myproject/data1812
launches the file mydo.do and passes the argument of a particular directory to the do-file. Inside the do-file you can grab the argument as
local myfolder "`1'"
i.e. the thing passed is passed as local macro 1. (Any other arguments would be local macros 2, 3, etc.)
Make sure your references to locations generally and files in particular are relative within the do-file and run the do-file from the parent directory.
Use global macros within your main do-file for locations and then re-define them within a master do-file which you run first.
Notes: It's best to use forward slashes, even under Windows; Stata will translate. Also, if there are embedded spaces, bind the whole thing in double quotes.
do mydo "d:/my project/data1812"
The second seems closest to your preference for not wiring in particular locations. But if you are using files from different places you have to tell Stata somehow where they are....
Nick's comment above gives the answer: c(pwd). This gives you a relative starting point for later commands, e.g. opening a dataset in the data folder:
use `c(pwd)'/data/yourdata, clear
Your problem might be that double-clicking a do-file does not cause Stata to set the working directory to its folder (while it does for datasets, which is inconsistent and not necessarily helpful).
There is no particular solution to that issue, except perhaps by writing your project folder path into a global macro set at startup by your profile.do file in your Stata application folder.
I teach classes of students and have them set their working directory with such a system. It works alright.
Paths to do-file in Stata
Several years has passed but the answer is still the same: there is no direct way to determine the location of a current do-file. The discussion around this topic has been raised many times on the Statalist. You can find plenty of useful tips here (just a brief overview, more discussion on the Statalist):
https://www.stata.com/statalist/archive/2007-09/msg00156.html
https://www.stata.com/statalist/archive/2013-07/msg00664.html
https://www.statalist.org/forums/forum/general-stata-discussion/general/1378783-do-i-have-to-specify-a-directory
In addition to those and Nick Cox and Fr. answers, I propose my humble solution to a collaborative work in Stata (that works on different machines both on Windows and Linux). It does not require additional modules and depends only on how you organize your materials in folders.
Tip 1. cd to your working directory with a hint -cap- and keep the -cd- code in the beginning of a do-file:
cap cd "W:\Bonds\" //Collaborator 1
cap cd "C:\Users\StataUser\Desktop\ProjectForBonds\" //Collaborator 2
cap cd "/media/DATA/work_materials/Dropbox/MyProjects/Bonds/" //Collaborator 3: Linux machine
cap cd "D:/work_materials/Dropbox/MyProjects/Bonds/" //Collaborator 3: PC
cap cd "E:/Projects/Dropbox/MyProjects/Bonds/" //Collaborator 3: Laptop
-cap- evades possible errors if a directory does not exist, so every user will get to his own working directory of the project. After -cd-ing to that directory you can save the path as a global variable and use it further in the code (if that is necessary):
global cdpath = "`c(pwd)'"
di "$cdpath" //show current folder
di `"{browse `"$cdpath"':Current folder}"' //optional: click to open the folder in the explorer
Hint: as Nick Cox mentioned, use "/" instead of "\". When you combine "\" with global/local variables, Stata treats this as a combination with an escape symbol (to be able to use symbols like ` and $ in strings), so using "\" may corrupt your browsing strategy. Check it via this code:
global cdpath = "`c(pwd)'"
di "$cdpath"
local i = 1
cap noi use "$cdpath\`i'\auto", clear
cap noi use "$cdpath/`i'/auto", clear
Tip 2. Keep the same folder structure by creating directories within Stata:
cap mkdir "./Temp"
cap mkdir "./Graphs"
Where "." means the current working directory. So you create "Temp" and "Graphs" folders inside the working directory. There you can store your temporary datasets, place graphs, etc.
You don't need to worry if a directory exists: -cap- alleviates this issue.
Tip 3. When saving/opening/deleting files (data, graphs, logs, etc.) explicitly tell Stata to use the relative paths:
use "./SourceData", clear
graph export "./Graphs/RollingBond.png", as(png) replace
save "./Temp/Years.dta", replace
save "./FinalBond.dta", replace
cap erase "./Temp/Years.dta"
Stata will know that you are still in your root folder and work relative to that folder.
And of course you can write full paths like this:
save "$cdpath/Temp/FinalBond.dta", replace
These tips work on both Windows and Unix and only requires to write for a new user the -cap cd "..."-. Very useful when you or your collaborator work from a thumbdrive and don't have access to any other place on a computer.