making sure program is in a terminal - c++

I was trying to add colors to some strings that have to be displayed in a terminal using ansi escape code. So far I haven't grasped the whole ascii escapes code thing, just trying out by copy pasting some escape codes. Then saw this answer which asked to verify that program should check that its being executed in a terminal or else continue without polluting strings with escape codes?
Answer explains to use a *nix based function isatty() which I found out resides in unistd.h which in turn wasn't promoted to cunistd by cpp standard based on my understanding that it wasn't in c's standard at first place.I tried to search SO again but wasn't able to understand well. Now I have two questions regarding this :
In what environment(right word?) can a program - using ascii escape codes, be executed that it requires an initial check? since I'm bulding for cli only.
What would be a proper solution according to ISO cpp standards for handling this issue? using unistd.h? would this use confine to modern cpp practices?
Also is there anything I should read/understand before dealing with ansi/colors related thing?

On a POSIX system (like Linux or OSX) the isatty function is indeed the correct function to determine if you're outputting to a terminal or not.
Use it as this
if (isatty(STDOUT_FILENO))
{
// Output using VT100 control codes
}
else
{
// Output is not a TTY, could be a pipe or redirected to a file
// Use normal output without control codes
}

Related

How can MSVC with /TC option compile corecrt libs(like stdio), written in C++?

In order to find answer to my own question How to use ESC sequences to set foreground colors?
I tried to find out how printf() itself works, and then maybe create my own function, which only accepts RGB and then automatically applies this color as an escape sequence to VT100 emulator of windows console. But eventually as I started digging into the code I discovered, that the most of IO, as well as stdin and stdout are written in C++ as well as string validator for printf format string.
As I was taught, in order to execute the program, compiler does all-the-way-back inclusion up to point, where all the text from all the included libs is pasted in your code. But my compiler is set to C only, so it can't compile C++ code. How could this happen? And is there other way to write stdout with escape codes already known to me(\033[%d;%d;%d;%d;%dm), though pushing the limitations of the console output?

Forcing a terminal windowl of set size to open in C++

My question regards c++ and trying to create a window to ensure my output is all fit into a single line. The only way I can think to do this is to force another window to open up upon running the program and have the output appear there.
Does anyone know how to do this?
I am using XCode on my Mac. Anything Helps!
The best you can do is to adjust your code to format the line within the bounds of the terminal you are using. For this, on OSX, you will need to use (and link) against termcap (short for 'terminal capabilities')
See also this one.

Change Console Code Page in Windows C++

I'm trying to output UTF8 characters in the Windows command line. I can't seem to get the function, setConsoleOutputCP to work. I also heard that you had to change the font to "Lucida Grande" for it to work but I can't get that working either. Can someone please provide me with a short example of how to use these functions to correctly output UTF-8 characters to the console?
Also I heard that those functions don't work in Windows XP, is there a better alternative to those functions which will work in Windows XP?
[I know this question is old and was about Windows XP, but it still seemed like a good place to drop this information so I (and maybe others) can find it again in the future.]
Support for Unicode in CMD windows has improved in newer versions of Windows. This program will work on Windows 10.
#include <iostream>
#include <Windows.h>
class UTF8CodePage {
public:
UTF8CodePage() : m_old_code_page(::GetConsoleOutputCP()) {
::SetConsoleOutputCP(CP_UTF8);
}
~UTF8CodePage() { ::SetConsoleOutputCP(m_old_code_page); }
private:
UINT m_old_code_page;
};
int main() {
UTF8CodePage use_utf8;
const char *text = u8"This text is in UTF-8. ¡Olé! 佻\n";
std::cout << text;
return 0;
}
I made an RAII class to ensure the code page is restored because it would be rude to leave the code page changed if the user had purposely selected a specific one. All the Windows-specific code (SetConsoleOutputCP) is contained within that class. The definition of the use_utf8 variable in main changes the code page to UTF-8, and that code page will stay in effect until the variable is destructed at the end of the scope.
Note that I used the u8 prefix on the string literal, which is a newer feature of C++ to ensure that the string is encoded using UTF-8 regardless of the encoding used for the source file. You don't have to use that feature if you have another way to make a string of valid UTF-8 text.
You still have to be sure that the CMD window is using a font that supports the glyphs you need. I don't think there's a way to get font linking automatically.
But this will at least show a the replacement character if the font is missing the glyph. For example, on my window, the ¡Olé! looks right but the CJK glyph is shown approximately like �. If the user copies that replacement character, the clipboard will receive the original glyph, so they can paste it into other programs without any loss of fidelity.
Note that command line parameters you get from main's argv will be in the original code page. One way to work around this is to get the unconverted "wide" command line with GetCommandLineW, convert it to UTF-8 with WideToMultibyte, and then parse it yourself. Alternatively, you can pass the result of GetCommandLineW to CommandLineToArgvW, which will parse it, and then you'd convert each argument to UTF-8.
Finally, note that changing the code page affects only the output. If you input text from the user, it arrives encoded using the original code page (often called the OEM code page).
TODO: Figure out input. SetConsoleCP isn't doing what I think the documentation says it should do.
Windows console doesn't play nice with UNICODE and particularly with UTF-8.
Setting a console code page to utf-8 won't work.
One approach is to use WideCharToMultiByte() (or something else) to convert the text to UTF-16, then MultiByteToWideChar() (or something else) to convert to a localised ISO encoding. The set the console code page to the ISO code page.
Its ugly, but it sort of works.
In short: SetConsoleOutputCP CP_UTF8 and cout/wcout dont work together by default.
Though windows CRT supports utf-8 output, a robust way to output to console utf-8 chars is to convert them into a console current codepage, especially if you want to use count/wcout.
Standard high level functions of basic_ostream does not work properly with utf-8 by default.
I've seen usage of MultiByteToWideChar and WideCharToMultiByte with CP_OEMCP and CP_UTF8 parameters.
You may setup your application environment, including console font via SetCurrentConsoleFontEx but it works only from Vista and Server 2008.
Also, check this about cout and console.
_setmode and wprintf works together as well, but this may lead to crash for non-wide char functions.
The problem occurs because there is a difference of codepage that uses windows in your console with the encoding of your source code text file.
Qt uses utf-8 by default, but another editor can use another one. So you must to verify which one you're using.
To change to utf-8 use:
#include <windows.h>
SetConsoleOutputCP(CP_UTF8);

Prevent mixing of console output and written text

I have a C++ console application that prints some output constantly while it also accepts commands (using std::cin) from the user - output and input happen in separate threads.
If I write a text while some output appears the written text is mixed with application output. How can I prevent this behaviour?
To solve this problem, I need to display the program one line above the line where the text is typed. I'd inspire myself in Minecraft Bukkit server's solution - however I need the same for C++.
Assuming you want the output to appear while things are being typed, you'll need some screen control facilities to have the output go somewhere different than the input area. If I were tasked to implement something like this writing to a terminal I would refresh my ncurses experience. I realize you are on a Windows console and I have no idea if the Windows console is capable of the screen control needed to make it happen.
You can possibly tie custom stream buffers into std::cin and std::cout using the curses functionality under the hood but it may not be worth it. In any case, it isn't entirely trivial.
There's a windows port of ncurses called pdcurses. But if you are using visual studio there's a simple function provided called SetConsoleCursorPosition()

Get trigger from console in C++

I am writing an application for a robot.
The required UI for the application is described in the pseudo-code below:
while(true){
if (spacebar is not pressed){
//do something
}
else{
sleep(1); //wait for a second
}
}
If I use cin or some other console input reading function then it will wait for user to press something. How do I ensure that it does not wait to get any input?
I am using Ubuntu. But I do not want it to be OS-specific.
Answers here seem to be OS specific.
Terminal Level input
What you are asking for is fairly close to the hardware (key-press / key-release) compared to the "standard input/output" stream concepts. So your implementation would have to be OS specific. Having said that the library to use is curses[1] which has been around for a long time and is standard on a lot of Un*x platforms. The GNU ncurses flavor compiles for pretty much all of them, it is a standard install in almost all Linux environments, and where it isn't installed by default you can find it. It also works well in Windows (cygwin), os/2 and a bunch of embedded systems etc. so you should be able to write a fairly portable software using curses that does what you want.
It's not too clear what you're asking for. In the if, is the
condition based on whether a space character has been entered,
or whether the user is currently holding down the space bar? In
the first case, you need something like curses (a portable
library which does gets each character as it was entered,
without echo). In the second, I don't think that there is
a portable solution. Even non-portably, you might not be able
to get it if your program is reading from a terminal window
(e.g. xterm); this sort of information is typically only present
as window events, when you created the window in your program.