DaniWeb IT Discussion Community

DaniWeb IT Discussion Community (http://www.daniweb.com/forums/index.php)
-   C++ (http://www.daniweb.com/forums/forum8.html)
-   -   how to identify which OS I am using (http://www.daniweb.com/forums/thread148611.html)

onemanclapping Oct 1st, 2008 9:20 pm
how to identify which OS I am using
 
hello. I'm doing a program in c++ and I need to use a system call to "clear" my screen.
for linux I use system("clear") but in windows the same is system("clr").
is there some way to find which OS is being used at the moment of execution so the program can decide whether it should use "clear" ou "clr"?
thanks in advance :)

dmanw100 Oct 1st, 2008 9:30 pm
Re: how to identify which OS I am using
 
There is no way to determine what OS the program is running on. Perhaps make two functions, and if say the windows function fails, run the Linux function.

onemanclapping Oct 1st, 2008 9:43 pm
Re: how to identify which OS I am using
 
Quote:

Originally Posted by dmanw100 (Post 703116)
There is no way to determine what OS the program is running on. Perhaps make two functions, and if say the windows function fails, run the Linux function.

oh, ok, no problem.
how can my program tell if the windows function has failed? because if "clr" works and then I call "clear", there will be an output error message.

dmanw100 Oct 1st, 2008 9:52 pm
Re: how to identify which OS I am using
 
The best way to do this would be know what OS your program will be working on. I think if you put the Windows call in a function and set it to return a bool true if successful and false if not (using an if statement) then you would be able to determine if you should call the other function.

Ancient Dragon Oct 1st, 2008 9:55 pm
Re: how to identify which OS I am using
 
The program must know what operating system its running under because it has to be recompiled for each os. Add some sort of preprocessor directive that tells the program what os its being compiled for. For example, you might put the define _WIN32 in the makefile when compiled for MS-Windows and _UNIX in another make file when being compiled for *nix os. Inside the program you can use that macro to determine which operating system its being compiled for.
#ifdef _WIN32
// do something for MS-Windows
#elif defined(_UNIX)
// beging compiled for *nix
#edndif

Ancient Dragon Oct 1st, 2008 9:57 pm
Re: how to identify which OS I am using
 
Quote:

Originally Posted by dmanw100 (Post 703128)
The best way to do this would be know what OS your program will be working on. I think if you put the Windows call in a function and set it to return a bool true if successful and false if not (using an if statement) then you would be able to determine if you should call the other function.

\


Not really. If the program is being compiled for *nix then the MS-Windows win32 api functions are not even available to the program, so it is impossible for the program to call it.

onemanclapping Oct 1st, 2008 10:05 pm
Re: how to identify which OS I am using
 
Quote:

Originally Posted by Ancient Dragon (Post 703129)
Inside the program you can use that macro to determine which operating system its being compiled for.
#ifdef _WIN32
// do something for MS-Windows
#elif defined(_UNIX)
// beging compiled for *nix
#edndif

Once again, thank you very much for your help in another thread of mine!
so you think this should work?
void clearScreen()
{
        #ifdef _WIN32
        system("cls");
        #elif defined(_UNIX)
        system("clear");
        #endif
}
I'm sorry to be asking but I don't have a windows system at the moment to try it :/

Ancient Dragon Oct 1st, 2008 10:10 pm
Re: how to identify which OS I am using
 
That will work providing you create the makefiles for each os as I described previously.

Duoas Oct 1st, 2008 11:40 pm
Re: how to identify which OS I am using
 
The exact macro to test for depends on OS and compiler. Here is a handy reference for Pre-defined C/C++ Compiler Macros.

Unless you have been careful to predefine specific macros in your makefiles as AD instructed, you should test for all the possible macros that you might expect. On Windows, I usually have something like
#if defined(__WIN32__) || defined(__WIN32) || defined(_WIN32) || defined(WIN32)
  #define __WIN32__
#endif

...

#ifdef __WIN32__
  // windows stuff here
#elif defined( ... )
  // other stuff here
#else
  // generic stuff here
#endif
Hope this helps.

onemanclapping Oct 2nd, 2008 3:27 pm
Re: how to identify which OS I am using
 
Quote:

Originally Posted by Ancient Dragon (Post 703135)
That will work providing you create the makefiles for each os as I described previously.

what do you mean by "create the makefiles for each os"? sorry, I'm a bit of a noob :/

I did:
#include <iostream>
using std::cout;
using std::cin;
using std::endl;

void clearScreen()
{
        #ifdef _WIN32
        system("cls");
        #elif defined(_UNIX)
        system("clear");
        #endif
}

int main()
{
        cout << "coco" << endl;
        cin.get();
        clearScreen();
        cout << "coco2" << endl;
}

and the result:
omc@linus-marx:~$ /home/omc/workspace/LigaSagres/Debug/LigaSagres
coco

coco2
omc@linus-marx:~$

so it didn't work. I guess maybe because I have not created "the makefiles for each os"

Sci@phy Oct 2nd, 2008 3:55 pm
Re: how to identify which OS I am using
 
Unix has various flags.
It doesn't have to do with makefiles.

Try writing instead of _UNIX:
_unix, unix, _UNIX_, UNIX... etc...

The best thing is: see what compiler are you using, and then look at its documentation, because compilers are setting those flags, and different compilers name different names (for exactly, or almost, the same thing)

skatamatic Oct 2nd, 2008 5:04 pm
Re: how to identify which OS I am using
 
I would sugguest, for the sake of portability, you never use system() calls. Instead clear the screen manually, or just print a large number of end lines.

skatamatic Oct 2nd, 2008 5:08 pm
Re: how to identify which OS I am using
 
To do the actual OS test, I would just check if c:\boot.ini exists. In the case of vista, since it uses a different booting scheme, you might want to check for another windows-specific system file, altough you would need elevated permissions to look inside the windows folder (i think). To do this, just use the fstream, open the file to be tested via ios::in, and test if it actually opened with .is_open() . If the windows files don't exist, assume linux. This is a bit of a band-aid but is a fairly surefire method of getting the OS.

ArkM Oct 2nd, 2008 6:00 pm
Re: how to identify which OS I am using
 
I think we have an impressive example of a false problem.

If you want to clear console window in portable manner, use portable direct console i/o library (pdcurses, for example, or others). That's the only right answer. May be a suitable ersatz of such libraries is <conio.h> stuff implemented with minimal variations in most of C and C++ programming systems. If you need to use standard console i/o (stdio.h or iostream), never use clear screen operation in your program interface design: no such entity as a screen in C and C++ stream i/o models.

As usually you can't run executable module on different OS in native mode, so the question "is there some way to find which OS is being used at the moment of execution so the program can decide..." is a senseless sentence. The obvious answer is "your program compiled and linked for OS1 can't run on OS2 so it find nothing on OS2, moreover it can't find itself on OS2".

It's the other question: "How to write portable sources which can select proper pieces of codes for different OS by C++ conditional compilation features?". Download good portable library (or system) and look at its configuration header. Of course, it looks like Ancient Dragon's example. But it's the other story and it's not so simple in common case.

Duoas Oct 2nd, 2008 6:20 pm
Re: how to identify which OS I am using
 
If this is just some homework problem, you could try one, then the other. Only one will work:
if (system( "clear" )) system( "cls" );

However, like ArkM said, better to do it the Right Way.

onemanclapping Oct 2nd, 2008 6:33 pm
Re: how to identify which OS I am using
 
Quote:

Originally Posted by ArkM (Post 703712)
Download good portable library (or system) and look at its configuration header.

Thanks for your help. Which library do you suggest? Because just printing empty lines won't really work, as this way the program contents will always apeear at the bottom of the screen and that's no good for me :/

Is there any method I can do this without using a library? Because it is for this term's project that we should do ourselves, and maybe the teacher won't find it funny for me to use libraries made by others...

Thanks again!

Ancient Dragon Oct 2nd, 2008 7:36 pm
Re: how to identify which OS I am using
 
Quote:

Originally Posted by onemanclapping (Post 703617)
what do you mean by "create the makefiles for each os"? sorry, I'm a bit of a noob :/

I did:
#include <iostream>
using std::cout;
using std::cin;
using std::endl;

void clearScreen()
{
        #ifdef _WIN32
        system("cls");
        #elif defined(_UNIX)
        system("clear");
        #endif
}

int main()
{
        cout << "coco" << endl;
        cin.get();
        clearScreen();
        cout << "coco2" << endl;
}

and the result:
omc@linus-marx:~$ /home/omc/workspace/LigaSagres/Debug/LigaSagres
coco

coco2
omc@linus-marx:~$

so it didn't work. I guess maybe because I have not created "the makefiles for each os"

What do you mean by "it didn't work" ? I don't know what that stuff is that you posted.

"makefile for each os" means that you have to compile your program in each os -- once under *nix and again under MS-Windows. You can't compile once and run on both operating systems -- that won't work.

If you use g++ compiler then you can probably have one source file and use the same compiler on both os. You will need a version of g++ for unix and another version of g++ for MS-Windows.

stilllearning Oct 2nd, 2008 8:26 pm
Re: how to identify which OS I am using
 
for example on Linux you could compile using

g++ -D_LINUX file.cpp -o output # turns on the #define _LINUX

and on windows using

g++ -D_WIN32 file.cpp -o output #turns on #define _WIN32

So if you had a makefile on both systems, you could set your compiler flags to reflect the defines you need.

Duoas Oct 3rd, 2008 12:56 am
Re: how to identify which OS I am using
 
Sigh. You know, you really shouldn't be dinking with the screen at all. But if all you want is something to clear the screen in Win32 and POSIX, here are a couple of functions. Your teacher will know you didn't write them yourself!

// clearscreen.cpp

#include <iostream>
#include <string>

#if defined(__WIN32__) || defined(__WIN32) || defined(_WIN32) || defined(WIN32) || defined(__TOS_WIN__) || defined(__WINDOWS__)
  #ifndef __WIN32__
    #define __WIN32__
  #endif
  #include <windows.h>
#else
  #include <unistd.h>
  #ifdef _POSIX_VERSION
    #ifndef __UNIX__
      #define __UNIX__
    #endif
    #include <term.h>
  #endif
#endif

#if !defined(__WIN32__) && !defined(__UNIX__)
  #warning Works best on a Windows or POSIX platform.
#endif

void clearscreen()
  {
  #if defined(__WIN32__)

    HANDLE                    hStdOut;
    CONSOLE_SCREEN_BUFFER_INFO csbi;
    DWORD                      count;
    DWORD                      cellCount;
    COORD                      homeCoords = { 0, 0 };

    hStdOut = GetStdHandle( STD_OUTPUT_HANDLE );
    if (hStdOut == INVALID_HANDLE_VALUE) return;

    /* Get the number of cells in the current buffer */
    if (!GetConsoleScreenBufferInfo( hStdOut, &csbi )) return;
    cellCount = csbi.dwSize.X *csbi.dwSize.Y;

    /* Fill the entire buffer with spaces */
    if (!FillConsoleOutputCharacter(
      hStdOut,
      (TCHAR) ' ',
      cellCount,
      homeCoords,
      &count
      )) return;

    /* Fill the entire buffer with the current colors and attributes */
    if (!FillConsoleOutputAttribute(
      hStdOut,
      csbi.wAttributes,
      cellCount,
      homeCoords,
      &count
      )) return;

    /* Move the cursor home */
    SetConsoleCursorPosition( hStdOut, homeCoords );

  #elif defined(__UNIX__)

    static char* console_clearscreen = 0;
    if (!console_clearscreen)
      {
      int result;
      setupterm( NULL, STDOUT_FILENO, &result );
      if (result > 0)
        console_clearscreen = tigetstr( "clear" );
      }
    if (console_clearscreen)
      putp( console_clearscreen );

  #else
    std::cout << std::string( 100, '\n' );
  #endif
  }

// end clearscreen.cpp
// clearscreen.hpp

#ifndef CLEARSCREEN_HPP
#define CLEARSCREEN_HPP

void clearscreen();

#endif

// end clearscreen.hpp
Enjoy.

ArkM Oct 3rd, 2008 3:24 am
Re: how to identify which OS I am using
 
I think Duodas have posted a good example of multilevel environment recognition with subsequent macros standartisation (#define __WIN32__, for example). More complicated example from the Boost library:
http://www.boost.org/doc/libs/1_36_0...orm_config.hpp

The key point is: don't dissipate OS/compiler dependencies over all your codes. Incapsulate all this stuff in the only .h header file. Declare your own portable functions (and data structures) in this file. For example, suppose its name is omgconio.h:
#ifndef OMGCONIO_H
#define OMGCONIO_H
...
/** Explain ClrScr functionality */
void ClrScr();
int Peek();
bool KbHit();
int GetCh();
...
#endif
Use only these functions calls in your source(s).

Create omgconio.cpp file with these functions inplementation. Place all OS/compiler selecting conditional compilation directives in this file only. Add omgconio.h and omgconio.cpp files to your projects.

Now you know where is OS/compiler dependency incapsulated if you will be ready to expand or correct your platform independent direct console i/o support.


All times are GMT -4. The time now is 9:24 pm.

Forum system based on vBulletin Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.
©2003 - 2009 DaniWeb® LLC