the linux and windows about the color - c

Recently, I've been having a problem.
#include <stdio.h>
#include <stdlib.h>
void main()
{
system("color 1F");
}
This can be printed Windows, but not in the Linux. Why?

Nothing to do with c, you're performing a system call on a command that doesn't necessarily exist.
color exists in the Windows shell, but doesn't on Linux. Your code is just not portable on Linux as-is.
Linux has its own way of doing it. You should check which OS you're running on and call the setterm instead for instance if you detect Linux (or at compilation time), so you already have Windows & Linux covered.
As a portable alternative, standard ANSI escape sequences are also widely available on a lot of OSes (For Windows, you need Windows 10, though)

Related

How do I get the User's operating system?

I am writing a C program, part of which requires me to get the User's operating system. For example, to get the home directory I can do the following:
const char *homedir;
homedir = getpwuid(getuid())->pw_dir;
printf("Home dir: %s\n",homedir);
I can not locate anything related to the OS in pwd.h is there a different file I should be looking at ?
Most of the times (it's not guaranteed), a C compiler defines macros that identify the current operating system (the macro-family, at the very least).
Eg. to identify Windows, Linux and Mac you could do:
#import <stdio.h>
typedef enum {
UNKNOWN,
WINDOWS,
LINUX,
OSX
} OS;
OS current_os();
int main() {
printf("%d",current_os());
return 0;
}
OS current_os() {
#ifdef _WIN32
return WINDOWS;
#elif (defined(__APPLE__) && defined(__MACH__))
return OSX;
#elif defined(__gnu_linux__)
return LINUX;
#else
return UNKNOWN;
#endif
}
On my Mac this prints 3, like it's supposed to do.
You can find a comprehensive list of those macros here.
On SVr4 and POSIX.1-2001 and later compliant UNIXes, use uname() -- for more info, man 2 uname to info about which UNIX, kernel version, and hardware identifier you are on.
Not sure for non-UNIX.
http://man7.org/linux/man-pages/man2/uname.2.html
On Windows, you'll use Win API functions to get exact version (such as GetVersionEx API call).
On Linux - you can use uname(struct utsname *buf) call (man 2 uname).
Other platforms may provide different APIs.
If you want to be portable across operating systems, you should provide a layer of abstraction that hides OS-specific calls and compile-in proper platform-specific implementation that shares a common interface.
Abstractions - this is The Way in cross-platform programming.
Alternatively, you may use pre-processor, which provides some basic platform information at compile-time. Preprocessor is used quite often to select platform-specific code to compile.

Achieving normal volume for '\a' output from C program on Windows 7

I have written a simple C program that outputs '\a' to the standard output via printf(). I have compiled it with gcc under Cygwin on a PC running Windows 7. The sound I hear when I execute the program is a VERY faint version of the one of the usual Windows alert sounds (it sounds like a chord being struck on some kind of musical instrument). But I cannot get a sound that has the usual volume of this sound. Is there a way to get that volume?
Output '\a' with printf() normaly outputs a beep through the integrated pc-speaker. To play a veep via the soundcard use MessageBeep from the WinAPI.
For example:
#include <Windows.h>
int main() {
MessageBeep(MB_ICONERROR);
return 0;
}

Determine OS during runtime

Neither ISO C nor POSIX offer functionality to determine the underlying OS during runtime. From a theoretical point of view, it doesn't matter since C offers wrappers for the most common system calls, and from a nit-picking point of view, there doesn't even have to be an underlying OS.
However, in many real-world scenarios, it has proven helpful to know more about the host environment than C is willing to share, e.g. in order to find out where to store config files or how to call select(), so:
Is there an idiomatic way for an application written in C to determine the underlying OS during runtime?
At least, can I easily decide between Linux, Windows, BSD and MacOS?
My current guess is to check for the existence of certain files/directories, such as C:\ or /, but this approach seems unreliable. Maybe querying a series of such sources may help to establish the notion of "OS fingerprints", thus increasing reliability. Anyway, I'm looking forward to your suggestions.
Actually, most systems have a uname command which shows the current kernel in use. On Mac OS, this is usually "Darwin", on Linux it's just plain "Linux", on Windows it's "ERROR" and FreeBSD will return "FreeBSD".
More complete list of uname outputs
I'm pretty sure that there's a C equivalent for uname, so you won't need system()
IF you are on a POSIX system, you can call uname() from <sys/utsname.h>.
This obviously isn't 100% portable, but I don't think there will be any method that can grant that at runtime.
see the man page for details
Runtime isn't the time to determine this, being that without epic kludges binaries for one platform won't run on another, you should just use #ifdefs around the platform sensitive code.
The accepted answer states uname, but doesn't provide a minimal working example, so here it is for anyone interested-hope it will save you the time it took for me:
#include <stdio.h>
#include <stdlib.h>
#include <sys/utsname.h>
int main(void) {
struct utsname buffer;
if (uname(&buffer) != 0) {
perror("uname");
exit(0);
}
printf("OS: %s\n", buffer.sysname);
return 0;
}
(Possible) Output:
OS: Linux
PS: Unfortunately, this uses a POSIX header: Compilation fails due to missing file sys/utsname.h, which most probably won't work in Windows.
if (strchr(getenv("PATH"),'\\'))
puts("You may be on windows...");
Even do I agree that "Runtime isn't the time to determine this..."

putwchar / getwchar encoding?

I'm writing code which runs on both Windows and Linux. The application works with unicode strings, and I'm looking to output them to the console using common code.
Will putwchar and getwchar do the trick? For example, can I provide unicode character values to these functions, and they will both display the same character on Linux and Windows?
You are about to enter a world of pain. Invariably *nix consoles prefer you to send them UTF-8 encoded char* data.
Windows on the other hand uses UTF-16 for its Unicode APIs and for console APIs I believe it is limited to UCS2.
You need probably need to find some library code that abstracts away the differences for you. I don't have a good recommendation for you but I am sure that putwchar and getwchar are not the solution.
One of the many ways to reconcile them is to use explicit conversion modes in Windows:
#ifdef _WIN32
#include <fcntl.h>
#include <io.h>
#endif
#include <wchar.h>
#include <stdio.h>
#include <locale.h>
int main()
{
#ifdef _WIN32
_setmode(_fileno(stdout), _O_WTEXT);
#else
setlocale(LC_ALL, "en_US.UTF-8");
#endif
fputws(L"Кошка\n", stdout);
}
tested with gcc 4.6.1 on Linux and Visual Studio 2010 on windows
There's also a _O_U8TEXT and _O_U16TEXT in Windows. Your mileage may vary.
See the putwchar man page on Linux. It says that the behavior depends on LC_CTYPE and says "It is reasonable to expect that putwchar() will actually write the multibyte sequence corresponding to the wide character wc." Similarly, getwchar() should read a multibyte sequence from standard input, and return it as a wide character.
Don't assume that they will read/write a constant number of bytes like they would in UCS2.
All that said, character-by-character I/O isn't usually the fastest solution, and when you start optimizing, do keep in mind that on Linux and Unix you'll be working in UTF-8.

Equivalent to Windows getch() for Mac/Linux crashes

I am using getch() and my app crashes instantly. Including when doing:
int main()
{
getch();
}
I can't find the link but supposedly the problem is that it needs to turn off buffering or something strange along those lines, and I still want cout to work along with cross platform code.
I was told to use std::cin.get(), but I'd like the app to quit when a key is pressed, not when the user typed in a letter or number then press enter to quit.
Is there any function for this? The code must work under Mac (my os) and Windows.
Linking/compiling is not an issue; I include <curses.h> and link with -lcurses in XCode, while Windows uses <conio.h>.
Have you looked in <curses.h> to see what the getch() function does?
Hint: OSX and Linux are not the same as Windows.
Specifically, as a macro in <curses.h>, we find:
#define getch() wgetch(stdscr)
Now, there appears, on your system, to be an actual function getch() in the curses library, but it expects stdscr to be set up, and that is done by the curses initialization functions (initscr() and relatives), and that is signally not done by your code. So, your code is invoking undefined behaviour by calling curses routines before the correct initialization is done, leading to the crash.
(Good hint from dmckee - it helped get the link line out of acidzombie24, which was important.)
To get to a point where a single key-stroke can be read and the program terminated cleanly, you have to do a good deal of work on Unix (OSX, Linux). You would have to trap the initial state of the terminal, arrange for an atexit() function - or some similar mechanism - to restore the state of the terminal, change the terminal from cooked mode into raw mode, then invoke a function to read a character (possibly just read(0, &c, 1)), and do your exit. There might be other ways to do it - but it certainly will involve some setup and teardown operations.
One book that might help is Advanced Unix Programming, 2nd Edn by Mark Rochkind; it covers terminal handling at the level needed. Alternatively, you can use <curses.h> properly - that will be simpler than a roll-your-own solution, and probably more reliable.
You have not exhibited a
#include <stdio.h>
or
#include <curses.h>
or similar line. Are you sure that you are linking against a library that includes getch()?
Use the cin.get() function for example:
#include <iostream>
using namespace std;
int main()
{
char input = cin.get();
cout << "You Pressed: " << input;
}
The program would then wait for you to press a key.
Once you have, the key you pressed would be printed to the screen.
The getch function is not available on Unix-like systems, but you can replace it with console commands through your compiler with the system function.
Usage:
In Windows you can use system("pause");
In Unix-like systems (such as OSX) you can use system("read -n1 -p ' ' key");
Note: system is declared in <stdlib.h>.

Resources