porting code from Linux to MinGW - c++

I am writing a small class which can create/remove/rename/search for files and directories on the PC.
I successfully wrote the class and run on Linux.
When I was trying to run the same Class Code in MinGW, it was giving an error.
I could narrow down to:
mkdir function in Linux, Cygwin has 2 Arguments (directory name , mode permissions)
but in MinGW has only one argument(directory name).
My query is : a) What is the best way to make the code work on both OSs. b) Though I never used, I heard Preprocessor directives can be put like #ifdefined .....#endif ..or some thing of that sort c) Is using Preprocessor directives a good programming practice. As I learnt, preprocessor directives should be used minimally.
Could some one help me in this:
Here is my Code which works on Linux and Cygwin:
#include "BioDatabase.h"
#include <dirent.h>
#include <sys/stat.h>
#include <stdio.h>
#include <unistd.h>
BioDatabase::BioDatabase() {
string s = getcwd(NULL,0);
changeDirectory(s,"*");
}
BioDatabase::BioDatabase(string directoryName, string extension)
{
changeDirectory(directoryName, extension);
}
bool BioDatabase::createDirectory(string st)
{
if( mkdir(st.c_str(),0755) == -1)
{
cerr <<endl<<"BOSERR-BioDatabase, createDirectory: Path or file function not found or Permission denied\n\n";
return false;
}
flag =1;
return true;
}

You could code something like
#if _POSIX_C_SOURCE
if( mkdir(st.c_str()) == -1)
#else
if ((mkdir(st.c_str(),0755) == -1)
#endif
See also feature_test_macros(7) man page.

1) you can use pre-processors to do one thing on one platform, and something different on another. EG:
#ifdef mingw32
/* windows specific code, like mkdir()... */
#else
/* other platform code, like a different way to call mkdir() */
#endif
2) Yes, you're absolutely right: limit using them as much as you can. but you'll quickly find out you can't avoid them entirely.
3) The best thing to do is to use a script that checks for
functionality rather than do it on a per-operating system basis.
Typically this involves writing a configure script (or
similar), which is a whole other learning curve. Still, it lets
you port to new platforms by checking for functionality rather than
adding the platform to a long list.

Related

Is there a way to open a new terminal window with code in C++?

I have an application and I want it to somehow open a new command line window for input. Is there a way to do this with C++?
To open a terminal or any other process, you need to call it.
For example, I use ubuntu OS and for open terminal If I say gnome-terminal, it will open it as I run my program.
This is that code:
#include <cstdlib>
int main()
{
std::system("gnome-terminal");
return 0;
}
For windows, you should call your cmd process. means that instead of gnome-terminal you need to write cmd or your process name
I'm not sure what is your "application" in this case. However, for applications to interact with each other, usually we would need some kind of APIs (Application Programming Interface), so that what you have on another application (a new terminal as you said) could be properly used in the "main" application.
If your desired result is just to get another terminal opened, we just have to call it. But remember, every Operating System has its own way to open a terminal, so if you like to automate everything, we have to use macros to check to current OS of the user, here is a suggestion:
#include <cstdlib>
int main()
{
#ifdef _WIN32
std::system("start program.exe");
// program.exe is app you have built to get input.
#endif
#ifdef _WIN64
std::system("start program.exe");
#endif
#ifdef __APPLE__
std::system("open program");
#endif
#ifdef __linux__
std::system("open program");
#endif
// #ifdef and #endif are just like if - statement.
}
Every compiler has the macros like _WIN32-stands for windows 32bit, _WIN64-windows 64bit, and so on. Its pretty handy to use them.
Hope this helps!

Clear Screen in Xcode

I am making a Library Management System in Xcode using C++. As Xcode does not support libraries such as conio.h and system "cls" does not work in it. What code should I use to clear the screen when I want it to shift from one menu to the other?
Check this out.
https://discussions.apple.com/thread/1064635?start=0&tstart=0
There is no direct way to do that; the system() command will not work on Mac (Unix). One option is to add a lot of spaces using code i.e.\n or other way is to use curses library
#include < curses.h > (curses.h) and then use system("clear"), which basically will do the same thing. So, its better to print spaces manually using the code rather than using some library.
One more thing you can do for POSIX (Unix, Linux, Mac OSX, etc) based systems [Note: I have not tested it myself]:
#include < unistd.h >
#include < term.h >
void ClearScreen()
{
if (!cur_term)
{
int result;
setupterm( NULL, STDOUT_FILENO, &result );
if (result <= 0) return;
}
putp( tigetstr( "clear" ) );
}
You'll have to link to the proper library (one of -lcurses, -lterminfo, etc.) to compile that last one. (Source: http://www.cplusplus.com/forum/articles/10515/)

Clearing the Console in C++

I am trying to clear the console in C++. I know printing a number of newlines is a bad practice, as it can be slow and is not always reliable to completely clear the console window, but I have researched multiple options and have found almost no other solutions besides system("cls"), which is an even worse option.
Essentially, I have used the line cout << string(100, '\n'); but I am getting a near-unidentifiable error when I try to run the program.
error C2679: binary '<<' : no operator found which takes a right-hand operand of type 'std::basic_string<_Elem,_Traits,_Ax>' (or there is no acceptable conversion)
I have also researched this, and found that most explanations were too complicated for me as a beginning C++ programmer to understand, or completely unrelated to my problem.
My questions are (1) is there a way to fix this error, and (2) could there be a better, cross-platform way of clearing the console other than printing 100 newlines?
I also heard of Console.clear(), but I'm unsure if this is cross-platform. From what I've seen, it looks more like a Windows command. I've also heard of the curses library, which I was willing to research and use, until I read somewhere that it was not recommended to use the functions which I am familiar with coupled with the curses library functions.
Thank you in advance!
About your error... you have to...
#include <iostream>
#include <string>
using namespace std;
If you are using just windows use windows console API.
If you are using a linux\unix terminal, use escape codes.
You can do a #if to choose between the two methods.
On linux\unix use the write function defined in in this way:
write(1,"\E[H\E[2J",7); // we use ANSI escape sequences here.
Here is the microsoft page that explain how to do that.
http://support.microsoft.com/kb/99261
The really bad console api microsoft use for the console always makes me angry :) why 100 lines of code to clear a screen? :)
Now the if... you should create a clearscreen.h file and a clearscreen.cpp file.
In clearscreen.h we just put our function.
void clearconsole();
In clearscreen.cpp we put our code for both operative systems
#ifdef _WIN32 || _WIN64
#include <windows.h>
void clearconsole()
{
...
// 100 lines of codes copied from microsoft article
}
#else
#include <unistd.h>
void clearconsole()
{
write(1,"\E[H\E[2J",7);
}
#endif
At a guess, your immediate problem is probably that you're missing an #include <string>.
Probably the most portable way of dealing with the screen is via ncurses. It's included in POSIX and most POSIX-like systems, and available as a library for most others (e.g., Windows) as well.
Edit: For what it's worth, clearing the screen on Windows doesn't require anywhere close to 100 lines of code.
#include <windows.h>
void clear_screen(char fill = ' ') {
COORD tl = {0,0};
CONSOLE_SCREEN_BUFFER_INFO s;
HANDLE console = GetStdHandle(STD_OUTPUT_HANDLE);
GetConsoleScreenBufferInfo(console, &s);
DWORD written, cells = s.dwSize.X * s.dwSize.Y;
FillConsoleOutputCharacter(console, fill, cells, tl, &written);
FillConsoleOutputAttribute(console, s.wAttributes, cells, tl, &written);
SetConsoleCursorPosition(console, tl);
}
#ifdef TEST
int main(){
clear_screen();
return 0;
}
#endif
I'm the first to say that the code is more verbose than I'd like -- but it's less than ten lines, not to mention a hundred. Even the version in the MS knowledgebase is actually less than 40 lines -- of which many are blank or comments.
In fairness, however, I feel obliged to admit assembly language code writing directly to the hardware (or using the BIOS) does end up quite a bit shorter.
I know this is a complete necro. But I figured out what I feel is a rather neat solution and thought I'd share it just in case someone has this problem in the future.
void clearConsole() {
#ifdef _WIN32
#include <iostream>
static const char* CSI = "\33[";
printf("%s%c%s%c", CSI, 'H', CSI, '2J');
#else
#include <unistd.h>
write(1, "\E[H\E[2J", 7);
#endif
}

How to redirect printf output back into code?

i'm writing a little c++ app to wrap around the opencv haar training function (namely cvCreateTreeCascadeClassifier). The function throws a whole load of output to the console and I wish to parse this output so that I can populate various variables in my code.
The function I wish to use is not part of the actual openCV library; instead it has to be built with my code as part of the project. All of the output from the the function is via printf.
Question: Is it possible to intercept the printf statements before they end up on the console? I've managed to redirect them using freopen but this seems a little clumsy as I then need to parse the file and then delete it when the function call is finished. Also, the function is likely to be running for several hours (and possibly even weeks!) so the size of the file might be an issue if its constantly being appended too.
Requirements: I need this app to be c++ and to run on both windows and linux (but have no problem with conditional compile statements if need be). I would also like to be able to still see my cout and cerr messages on the console (just not the printf).
My googling has removed my will to live! Can anyone help with a solution via either code example or pointers to places I should be looking for an answer?
Thanks
What you can do is:
create a pipe
make the writable end of the pipe the new stdout
read from the readable part of the pipe
Reading and writing should happen in different threads or you risk that your program starves on one end of the pipe.
Here's a sample how to do the redirection in unix & windows:
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
/* gcc defined unix */
#ifdef unix
#include <unistd.h>
#endif
#ifdef WIN32
#include <io.h>
#define pipe(X) _pipe(X,4096,O_BINARY)
#define fileno _fileno
#define dup2 _dup2
#define read _read
#endif
#include <assert.h>
int main()
{
int fds[2];
int res;
char buf[256];
int so;
res=pipe(fds);
assert(res==0);
so=fileno(stdout);
// close stdout handle and make the writable part of fds the new stdout.
res=dup2(fds[1],so);
assert(res!=-1);
printf("Hi there\n");
fflush(stdout);
// reading should happen in a different thread
res=read(fds[0],buf,sizeof(buf)-1);
assert(res>=0 && res<sizeof(buf));
buf[res]=0;
fprintf(stderr,"buf=>%s\n",buf);
return 0;
}
This code should print
buf=>Hi there
(I'm using assert here, because I am too lazy to do real error checking for this example)
Encapsulate the lib into an application, and pipe the application's output to your application. Now write a script so that you don't have to run the apps together every time with a pipe.
Take a look at: http://www.unix.com/programming/136225-reading-stdout-pipe.html it seems promising, but i never tried it.

How do I get the directory that a program is running from?

Is there a platform-agnostic and filesystem-agnostic method to obtain the full path of the directory from where a program is running using C/C++? Not to be confused with the current working directory. (Please don't suggest libraries unless they're standard ones like clib or STL.)
(If there's no platform/filesystem-agnostic method, suggestions that work in Windows and Linux for specific filesystems are welcome too.)
Here's code to get the full path to the executing app:
Variable declarations:
char pBuf[256];
size_t len = sizeof(pBuf);
Windows:
int bytes = GetModuleFileName(NULL, pBuf, len);
return bytes ? bytes : -1;
Linux:
int bytes = MIN(readlink("/proc/self/exe", pBuf, len), len - 1);
if(bytes >= 0)
pBuf[bytes] = '\0';
return bytes;
If you fetch the current directory when your program first starts, then you effectively have the directory your program was started from. Store the value in a variable and refer to it later in your program. This is distinct from the directory that holds the current executable program file. It isn't necessarily the same directory; if someone runs the program from a command prompt, then the program is being run from the command prompt's current working directory even though the program file lives elsewhere.
getcwd is a POSIX function and supported out of the box by all POSIX compliant platforms. You would not have to do anything special (apart from incliding the right headers unistd.h on Unix and direct.h on windows).
Since you are creating a C program it will link with the default c run time library which is linked to by ALL processes in the system (specially crafted exceptions avoided) and it will include this function by default. The CRT is never considered an external library because that provides the basic standard compliant interface to the OS.
On windows getcwd function has been deprecated in favour of _getcwd. I think you could use it in this fashion.
#include <stdio.h> /* defines FILENAME_MAX */
#ifdef WINDOWS
#include <direct.h>
#define GetCurrentDir _getcwd
#else
#include <unistd.h>
#define GetCurrentDir getcwd
#endif
char cCurrentPath[FILENAME_MAX];
if (!GetCurrentDir(cCurrentPath, sizeof(cCurrentPath)))
{
return errno;
}
cCurrentPath[sizeof(cCurrentPath) - 1] = '\0'; /* not really required */
printf ("The current working directory is %s", cCurrentPath);
This is from the cplusplus forum
On windows:
#include <string>
#include <windows.h>
std::string getexepath()
{
char result[ MAX_PATH ];
return std::string( result, GetModuleFileName( NULL, result, MAX_PATH ) );
}
On Linux:
#include <string>
#include <limits.h>
#include <unistd.h>
std::string getexepath()
{
char result[ PATH_MAX ];
ssize_t count = readlink( "/proc/self/exe", result, PATH_MAX );
return std::string( result, (count > 0) ? count : 0 );
}
On HP-UX:
#include <string>
#include <limits.h>
#define _PSTAT64
#include <sys/pstat.h>
#include <sys/types.h>
#include <unistd.h>
std::string getexepath()
{
char result[ PATH_MAX ];
struct pst_status ps;
if (pstat_getproc( &ps, sizeof( ps ), 0, getpid() ) < 0)
return std::string();
if (pstat_getpathname( result, PATH_MAX, &ps.pst_fid_text ) < 0)
return std::string();
return std::string( result );
}
If you want a standard way without libraries: No. The whole concept of a directory is not included in the standard.
If you agree that some (portable) dependency on a near-standard lib is okay: Use Boost's filesystem library and ask for the initial_path().
IMHO that's as close as you can get, with good karma (Boost is a well-established high quality set of libraries)
I know it is very late at the day to throw an answer at this one but I found that none of the answers were as useful to me as my own solution. A very simple way to get the path from your CWD to your bin folder is like this:
int main(int argc, char* argv[])
{
std::string argv_str(argv[0]);
std::string base = argv_str.substr(0, argv_str.find_last_of("/"));
}
You can now just use this as a base for your relative path. So for example I have this directory structure:
main
----> test
----> src
----> bin
and I want to compile my source code to bin and write a log to test I can just add this line to my code.
std::string pathToWrite = base + "/../test/test.log";
I have tried this approach on Linux using full path, alias etc. and it works just fine.
NOTE:
If you are on windows you should use a '\' as the file separator not '/'. You will have to escape this too for example:
std::string base = argv[0].substr(0, argv[0].find_last_of("\\"));
I think this should work but haven't tested, so comment would be appreciated if it works or a fix if not.
Filesystem TS is now a standard ( and supported by gcc 5.3+ and clang 3.9+ ), so you can use current_path() function from it:
std::string path = std::experimental::filesystem::current_path();
In gcc (5.3+) to include Filesystem you need to use:
#include <experimental/filesystem>
and link your code with -lstdc++fs flag.
If you want to use Filesystem with Microsoft Visual Studio, then read this.
No, there's no standard way. I believe that the C/C++ standards don't even consider the existence of directories (or other file system organizations).
On Windows the GetModuleFileName() will return the full path to the executable file of the current process when the hModule parameter is set to NULL. I can't help with Linux.
Also you should clarify whether you want the current directory or the directory that the program image/executable resides. As it stands your question is a little ambiguous on this point.
On Windows the simplest way is to use the _get_pgmptr function in stdlib.h to get a pointer to a string which represents the absolute path to the executable, including the executables name.
char* path;
_get_pgmptr(&path);
printf(path); // Example output: C:/Projects/Hello/World.exe
Maybe concatenate the current working directory with argv[0]? I'm not sure if that would work in Windows but it works in linux.
For example:
#include <stdio.h>
#include <unistd.h>
#include <string.h>
int main(int argc, char **argv) {
char the_path[256];
getcwd(the_path, 255);
strcat(the_path, "/");
strcat(the_path, argv[0]);
printf("%s\n", the_path);
return 0;
}
When run, it outputs:
jeremy#jeremy-desktop:~/Desktop$ ./test
/home/jeremy/Desktop/./test
For Win32 GetCurrentDirectory should do the trick.
You can not use argv[0] for that purpose, usually it does contain full path to the executable, but not nessesarily - process could be created with arbitrary value in the field.
Also mind you, the current directory and the directory with the executable are two different things, so getcwd() won't help you either.
On Windows use GetModuleFileName(), on Linux read /dev/proc/procID/.. files.
Just my two cents, but doesn't the following code portably work in C++17?
#include <iostream>
#include <filesystem>
namespace fs = std::filesystem;
int main(int argc, char* argv[])
{
std::cout << "Path is " << fs::path(argv[0]).parent_path() << '\n';
}
Seems to work for me on Linux at least.
Based on the previous idea, I now have:
std::filesystem::path prepend_exe_path(const std::string& filename, const std::string& exe_path = "");
With implementation:
fs::path prepend_exe_path(const std::string& filename, const std::string& exe_path)
{
static auto exe_parent_path = fs::path(exe_path).parent_path();
return exe_parent_path / filename;
}
And initialization trick in main():
(void) prepend_exe_path("", argv[0]);
Thanks #Sam Redway for the argv[0] idea. And of course, I understand that C++17 was not around for many years when the OP asked the question.
Just to belatedly pile on here,...
there is no standard solution, because the languages are agnostic of underlying file systems, so as others have said, the concept of a directory based file system is outside the scope of the c / c++ languages.
on top of that, you want not the current working directory, but the directory the program is running in, which must take into account how the program got to where it is - ie was it spawned as a new process via a fork, etc. To get the directory a program is running in, as the solutions have demonstrated, requires that you get that information from the process control structures of the operating system in question, which is the only authority on this question. Thus, by definition, its an OS specific solution.
#include <windows.h>
using namespace std;
// The directory path returned by native GetCurrentDirectory() no end backslash
string getCurrentDirectoryOnWindows()
{
const unsigned long maxDir = 260;
char currentDir[maxDir];
GetCurrentDirectory(maxDir, currentDir);
return string(currentDir);
}
For Windows system at console you can use system(dir) command. And console gives you information about directory and etc. Read about the dir command at cmd. But for Unix-like systems, I don't know... If this command is run, read bash command. ls does not display directory...
Example:
int main()
{
system("dir");
system("pause"); //this wait for Enter-key-press;
return 0;
}
Works with starting from C++11, using experimental filesystem, and C++14-C++17 as well using official filesystem.
application.h:
#pragma once
//
// https://en.cppreference.com/w/User:D41D8CD98F/feature_testing_macros
//
#ifdef __cpp_lib_filesystem
#include <filesystem>
#else
#include <experimental/filesystem>
namespace std {
namespace filesystem = experimental::filesystem;
}
#endif
std::filesystem::path getexepath();
application.cpp:
#include "application.h"
#ifdef _WIN32
#include <windows.h> //GetModuleFileNameW
#else
#include <limits.h>
#include <unistd.h> //readlink
#endif
std::filesystem::path getexepath()
{
#ifdef _WIN32
wchar_t path[MAX_PATH] = { 0 };
GetModuleFileNameW(NULL, path, MAX_PATH);
return path;
#else
char result[PATH_MAX];
ssize_t count = readlink("/proc/self/exe", result, PATH_MAX);
return std::string(result, (count > 0) ? count : 0);
#endif
}
For relative paths, here's what I did. I am aware of the age of this question, I simply want to contribute a simpler answer that works in the majority of cases:
Say you have a path like this:
"path/to/file/folder"
For some reason, Linux-built executables made in eclipse work fine with this. However, windows gets very confused if given a path like this to work with!
As stated above there are several ways to get the current path to the executable, but the easiest way I find works a charm in the majority of cases is appending this to the FRONT of your path:
"./path/to/file/folder"
Just adding "./" should get you sorted! :) Then you can start loading from whatever directory you wish, so long as it is with the executable itself.
EDIT: This won't work if you try to launch the executable from code::blocks if that's the development environment being used, as for some reason, code::blocks doesn't load stuff right... :D
EDIT2: Some new things I have found is that if you specify a static path like this one in your code (Assuming Example.data is something you need to load):
"resources/Example.data"
If you then launch your app from the actual directory (or in Windows, you make a shortcut, and set the working dir to your app dir) then it will work like that.
Keep this in mind when debugging issues related to missing resource/file paths. (Especially in IDEs that set the wrong working dir when launching a build exe from the IDE)
A library solution (although I know this was not asked for).
If you happen to use Qt:
QCoreApplication::applicationDirPath()
Path to the current .exe
#include <Windows.h>
std::wstring getexepathW()
{
wchar_t result[MAX_PATH];
return std::wstring(result, GetModuleFileNameW(NULL, result, MAX_PATH));
}
std::wcout << getexepathW() << std::endl;
// -------- OR --------
std::string getexepathA()
{
char result[MAX_PATH];
return std::string(result, GetModuleFileNameA(NULL, result, MAX_PATH));
}
std::cout << getexepathA() << std::endl;
This question was asked 15 years ago, so the existing answers are now incorrect. If you're using C++17 or greater, the solution is very straightforward today:
#include <filesystem>
std::cout << std::filesystem::current_path();
See cppreference.com for more information.
On POSIX platforms, you can use getcwd().
On Windows, you may use _getcwd(), as use of getcwd() has been deprecated.
For standard libraries, if Boost were standard enough for you, I would have suggested Boost::filesystem, but they seem to have removed path normalization from the proposal. You may have to wait until TR2 becomes readily available for a fully standard solution.
Boost Filesystem's initial_path() behaves like POSIX's getcwd(), and neither does what you want by itself, but appending argv[0] to either of them should do it.
You may note that the result is not always pretty--you may get things like /foo/bar/../../baz/a.out or /foo/bar//baz/a.out, but I believe that it always results in a valid path which names the executable (note that consecutive slashes in a path are collapsed to one).
I previously wrote a solution using envp (the third argument to main() which worked on Linux but didn't seem workable on Windows, so I'm essentially recommending the same solution as someone else did previously, but with the additional explanation of why it is actually correct even if the results are not pretty.
As Minok mentioned, there is no such functionality specified ini C standard or C++ standard. This is considered to be purely OS-specific feature and it is specified in POSIX standard, for example.
Thorsten79 has given good suggestion, it is Boost.Filesystem library. However, it may be inconvenient in case you don't want to have any link-time dependencies in binary form for your program.
A good alternative I would recommend is collection of 100% headers-only STLSoft C++ Libraries Matthew Wilson (author of must-read books about C++). There is portable facade PlatformSTL gives access to system-specific API: WinSTL for Windows and UnixSTL on Unix, so it is portable solution. All the system-specific elements are specified with use of traits and policies, so it is extensible framework. There is filesystem library provided, of course.
The linux bash command
which progname will report a path to program.
Even if one could issue the which command from within your program and direct the output to a tmp file and the program
subsequently reads that tmp file, it will not tell you if that program is the one executing. It only tells you where a program having that name is located.
What is required is to obtain your process id number, and to parse out the path to the name
In my program I want to know if the program was
executed from the user's bin directory or from another in the path
or from /usr/bin. /usr/bin would contain the supported version.
My feeling is that in Linux there is the one solution that is portable.
Use realpath() in stdlib.h like this:
char *working_dir_path = realpath(".", NULL);
The following worked well for me on macOS 10.15.7
brew install boost
main.cpp
#include <iostream>
#include <boost/filesystem.hpp>
int main(int argc, char* argv[]){
boost::filesystem::path p{argv[0]};
p = absolute(p).parent_path();
std::cout << p << std::endl;
return 0;
}
Compiling
g++ -Wall -std=c++11 -l boost_filesystem main.cpp