Text-cursor position handling in C (under Linux) - c

I'm trying to reposition the text-cursor to top left corner of the console each frame, so the resulted square rendered at the same position
#include <stdio.h>
#include <stdlib.h>
int main() {
while(1) {
printf("\u2554\u2550\u2550\u2550\u2557\n\u255A\u2550\u2550\u2550\u255D\n");
}
}
I found that this is possible in windows by including <windows.h>:
HANDLE hOut;
COORD Position;
hOut = GetStdHandle(STD_OUTPUT_HANDLE);
Position.X = 0;
Position.Y = 0;
SetConsoleCursorPosition(hOut,Position);
How can I do that in Ubuntu?

[update] Oops, sorry, I didn't notice the "[C]" tag and my answer was only referring to shell commands.
The actual answer is to use a curses-like library, like ncurses.
For example, the function you are looking for is typically move().
Original answer:
On Unix systems, moving the cursor depends on the type of the terminal you are using.
There are libraries like ncurses that aim to provide functionalities that are terminal-independent. tput is a command that uses ncurses to make some terminal capabilities (like moving the cursor) available to the command line:
tput cup 0 0
will put the cursor in the (0,0) position, whatever the terminal you are using (if such a terminal allows you to move the cursor)

Write \033[H to the console, and this will put the cursor in the top left corner of the terminal.
For that, the terminal must be ANSI compatible (for example, the xterm terminal or the linux console)
Anyway, I recommend you to use the ncurses library, which gives you many possibilities, apart of this, and in a manner that is terminal type independent (so it will run in almost any known terminal type, e.g. an hp terminal)

Related

C , linebreak without linefeed?

Silly question but,
Is it possible to break a line on stdout without the line feed using printf();? If not, any tips on how I would overwrite 2+ lines, if possible?
I'm trying to generate sort of a progress bar but on multiple lines.
Any ideas?
EDIT:
So yeah I accepted the below answer although it won't work for my specific case.
I'm trying to overwrite 2+lines
rather than a single line.
printf("12345\r");
fflush(stdout);
printf("67890\n");
The result of which is $ ./a.out 67890
But what I'm trying to achieve is have 2+ lines be overwritten with new data.
Similar to a progress bar but on 2+ lines except I have a percentage number for some data.
To rewrite all (or part) of a line, you need to use the correct number of backspace characters. Eg:
printf("some text");
printf("\b\b\b\bstuff");
Will output:
some stuff
This is fine for simple stuff; for something more complex you should use ncurses which uses ANSI-escape cleverness to manipulate the cursor around the screen.
If your terminal (or, much more likely, terminal emulator) supports VT100-style escape sequences, you can print specific code sequences to control the cursor position, clear some or all of the screen/window, etc.
For example, to move the cursor up 1 line:
printf("\x1b[A");
fflush(stdout);
To move the cursor up 2 lines, either do that twice or:
printf("\x1b[2A"});
fflush(stdout);
These are commonly referred to as ANSI escape codes; the link is to a Wikipedia article that lists many of them. They were first implemented by the old DEC VT-100 terminal, which is emulated by most modern terminals and emulators.
And this:
printf("\x1b[J");
fflush(stdout);
will clear part of the screen, from the current cursor position to the bottom.
These sequences should be enough to do what you need. (They might not work in a Windows command window.)
More portably, if your system supports it, you can use termcap or terminfo to determine the proper command sequences for your current terminal (as determined by the $TERM environment variable). The tput command lets you do this on the command line; man tput for more information. In practice, you're unlikely to find a system these days that supports termcap or terminfo with a terminal that's not VT100-compatible; printing raw escape sequences is strictly not portable, but probably good enough.
A suggestion: your program should probably have an option to inhibit any such control sequences; for example, if a user who wants to redirect the output to a file won't want to have those escape sequences in the file. Some programs use control sequences only if they can determine that stdout is a terminal, but an explicit option is also a good idea.
*UPDATE: *
Here's a program I threw together that demonstrates how to do this with the terminfo. It should work on just about any Unix-like system.
#include <stdio.h>
#include <stdlib.h>
#include <curses.h>
#include <term.h>
#include <unistd.h>
int main(void) {
const char *term = getenv("TERM");
if (term == NULL) {
fprintf(stderr, "TERM environment variable is not set\n");
exit(EXIT_FAILURE);
}
setterm(term);
for (int i = 0; i < 10; i ++) {
putp(tparm(clr_eos));
printf("%d\n%d\n", i, i+1);
sleep(1);
putp(tparm(parm_up_cursor, 2));
}
return 0;
}

How to change font size in console application using C

How can I change the font size of a printed font using c?
printf ("%c", map[x][y]);
I want to print an array larger than all the other text in the program. Is there a way to just make that statement print larger?
Although teppic's answer to use system() will work, it is rather intensively heavy-handed to call an external program just to do that. As for David RF' answer, it is hard-coded for a specific type of terminal (probably a VT100-compatible terminal type) and won't support the user's actual terminal type.
In C, you should use terminfo capabilities directly:
#include <term.h>
/* One-time initialization near the beginning of your program */
setupterm(NULL, STDOUT_FILENO, NULL);
/* Enter bold mode */
putp(enter_bold_mode);
printf("I am bold\n");
/* Turn it off! */
putp(exit_attribute_mode);
Still, as teppic notes, there is no support for changing the font size. That's under the user's control.
If you are under some unix, you can try to activate and deactivate bold text:
printf("\033[1m%c\033[0m", map[x][y]);
If it's Linux (and probably other forms of Unix) you could mess around with system to change a few terminal settings to make it stand out - though not the font size. This kind of thing would really only be suitable for simple programs, and it's obviously not portable:
#include <stdio.h>
#include <stdlib.h>
[...]
printf("Normal text\n");
system("setterm -bold on");
printf("Bold text\n");
system("setterm -bold off");
Otherwise there are various terminal sequences you can send directly via printf that will control most Unix terminal applications, e.g. \033[31m will change the text to red in an xterm. But these sequences can vary.
This code will work on Win32 applications (regardless of the subsystem used: WINDOWS or CONSOLE):
inline void setFontSize(int a, int b)
{
HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
PCONSOLE_FONT_INFOEX lpConsoleCurrentFontEx = new CONSOLE_FONT_INFOEX();
lpConsoleCurrentFontEx->cbSize = sizeof(CONSOLE_FONT_INFOEX);
GetCurrentConsoleFontEx(hStdOut, 0, lpConsoleCurrentFontEx);
lpConsoleCurrentFontEx->dwFontSize.X = a;
lpConsoleCurrentFontEx->dwFontSize.Y = b;
SetCurrentConsoleFontEx(hStdOut, 0, lpConsoleCurrentFontEx);
}
Then just call (for example):
setFontSize(20,20);

Adding Colour To Text In C With Bloodshed

Is this possible?
I know it's possible in the command prompt using COLOR ##
but is it possible in C using bloodshed?
Thanks,
What operating system? What terminal do you have available? Note that this has nothing to do with C, let alone bloodshed. You output a string which the terminal may or may not choose to interpret as a color. You have to see how to do that with your terminal. The solution of course is not portable. One such example for a terminal supporting escape sequences is
printf("\\x1b[1;33mThis is yellow\\x1b[m(Back to default)\n");
You may be interested in ANSI terminal's color escape sequences
You may also want to look for libraries that do that for limited number of terminals. For example, ncurses could help you in Linux.
If you're on *nix, osx, or using cygwin msys on windows, your terminal should support the ANSI sequences Fred Larson mentions (not sure about osx). The normal windows terminal does not. But bloodshed can use cygwin, so you're in luck.
Here's an example:
#include <stdio.h>
#define BOLDMAGENTA "\033[1;35m"
#define BOLDGREEN "\033[1;32m"
int main(void) {
printf("%shello %sworld\n", BOLDMAGENTA, BOLDGREEN);
return 0;
}
Note that this leaves the terminal in bright green, but if your prompt sets colours, that will get reset.
Here's some explanation of ANSI escape codes:
http://en.wikipedia.org/wiki/ANSI_escape_code

Why doesn't this code position the cursor correctly when I build it with Borland C++?

I found this code for a replacement gotoxy() function using C standard library only. apparently it compiles using GCC and works like the gotoxy() found in conio.h.
However I only have Borland C++ v5.5 compiler, this compiles fine but does not reposition the curser like gotoxy() in conio.h does. Can anybody verify the fact that this works when using GCC or tell me why it doesn't work using Borland?
#include<stdio.h>
#include<stdlib.h>
void gotoxy(int x, int y)
{
printf("%c[%d;%df", 0x1B, y, x);
}
int main()
{
gotoxy(10, 10);
printf("hello world");
}
The escape codes being used in your function depend on support being present in your terminal emulator. It may or may not work, depending on the environment you're using. For example, your program works as expected in Mac OS X's Terminal application, running bash in xterm compatibility mode.
You can read about ANSI escape codes for more information about this specific case, which is the "HVP – Horizontal and Vertical Position" command.
That code prints an ANSI escape sequence: <esc>[y;xf, so will only work on an ANSI terminal, or a terminal emulator that supports ANSI codes.
The issue isn't GCC vs BC++, but running in a unix-style terminal emulator that supports ANSI codes vs the Windows CMD window.
EDIT: try changing the body of gotoxy() to the following. The escape code in your sample moves the cursor to a previous line. The code ending in H should position the cursor to the requested (Y,X) coordinate.
printf("%c[%d;%dH", 0x1B, y, x);
EDIT2: since the asker is using the Windows CMD console, the correct solution is to use SetConsoleCursorPosition(). ANSI escapes aren't supported, or are incompletely supported in Win2k and later.

Color console in ANSI C?

Is it possible to color the console output in just plain ANSI C? Without an external library? Can this be done in Windows, Linux, or Mac OS X?
just plain ANSI C?
No. The C standard doesn't assume the stdout is a console or has color.
Can this be done in Windows, Linux, or Mac OS X?
Yes. See How can I print to the console in color on Mac OS X in a cross-platform manner? for Linux and Mac OS X.
For Windows, you may need to directly access the Console Functions if you want to avoid external libraries.
Yes, in Linux/ Mac it is possible using ANSI C89.
You can either manipulate the font and the color of the text.
using the following command:
printf("%c[0;00mHello, world!\n", 27); /* White color */
printf("%c[1;33mHello, world!\n", 27); /* Yellowish color */
printf("%c[1;34mHello, world!\n", 27); /* Blueish color */
Notice that the left part of the ";" (where the numbers 0, 1 are) manipulates the text font,
the right part of ";" manipulates the colors. You can experiment on your own and find out new colors.
This code compiles using "-ansi -pedantic" command with no warnings nor errors.
***** Edit *****
In Windows based systems you can achieve colorful console text/background of text using the following example:
#include <stdio.h>
#include <windows.h>
int main(void)
{
/* Point to our console */
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
int i = 0;
/* Iterate through colors */
for(; i < 255; i++)
{ /* i stands for color type: could refer to actual text color or background color of text */
SetConsoleTextAttribute(hConsole, i);
printf("Colorful text");
}
getchar();
return 0;
}
Good luck!
in Linux this can be done, if you you know the shell-specific control codes / Escape sequences.
Linux/OSX/Unix
On posix systems you can use the ANSI escape sequences.
Windows
On windows it is a bit more complicated, there are multiple solutions:
Win32 API
Using the Win32 API to set the output color before printing to the console using SetConsoleTextAttribute and friends. This is a lot more cumbersome than simply embedding ANSI escape sequences in your strings, and requires you to handle Windows as a special case.
Windows ANSI.SYS and Replacement
Older version of windows contained ANSI.SYS, but this has been removed in later versions. ANSICON is a replacement for this that you can install to get ANSI color code support in the windows command prompt: https://github.com/adoxa/ansicon
Embeddable no external dependencies solution
Here is a project that can be easily integrated into any existing project without relying on ANSI.SYS or ANSICON being installed.
It takes a string containing ANSI escape sequences and translates them to the relevant Win32 equivalent API functions: https://github.com/mattn/ansicolor-w32.c
It is true that ISO C knows nothing about the console being capable of displaying colors, however there is an ANSI norm for console capabilities management, based on escape character controls. This works transparently in Linux and Mac OS X, however it fails in Windows, in which you need to use the primitives of the Win32 API.
You can find below a very simple library that allows to clear the screen, show colors and locate the cursor in a specific coordinate, in a multiplatform way (Win32 & Unix-like systems).
It comes with plain C source files (.c and .h), doxygen documentation in Spanish (doc/), and a simple demo (main.c)
http://github.com/Baltasarq/cscrutil/

Resources