GNU/Linux replacements for Turbo C functions `clrscr` and `cprintf` - c

I just moved to Linux for just a month. I've used Borland Turbo C for C programming but some of these functions do not work in GNU/Linux, so looking for help.
These are some of the functions I would like to replace:
- gotoxy
- cprintf
- clrscr
- initgraph/graphics.h
I would appreciate some code examples showing how to use any replacements.

In linux, you can use the ncurses library to use the terminal as a text buffer: move the cursor around, and write text. It can also draw windows and other hi-level widgets.
For gotoxy see move and wmove from ncurses (link).
For cprintf see printw.
You can clear the screen simply with clear().
In ncurses you also need to refresh the screen with refresh() after printw and clear().
Example program, which uses all the mentioned functions in ncurses:
#include <curses.h>
int main(int argc, char *argv[])
{
initscr();
clear();
move(15, 20);
printw("Test program: %s", argv[0]);
refresh();
getch();
endwin();
return 0;
}
Compile in gcc with: gcc program.c -lcurses
As for graphics, you have to choose a particular library.
If you need a similar experience as the low-level graphics.h, you are probably looking for directfb or svgalib.
If you want to render graphics in a window, SDL will be helpful.

The functions you refer to are part of Borland's proprietary library for console applications. You want to read about ncurses.

About graphics.h
Regarding using graphics.h in Linux is an easy task. I had the same problem a week ago. Well you can goggle with search term "graphics.h in Linux", and you will get many links and here is one.
http://www.rajivnair.in/2007/07/graphicsh-in-gnulinux.html.
About Clear Screen
For that, you have many options.
And the one is,
using system("clear") but it needs stdlib.h and it is slower in performance.
Here two links for you...
How do I clear the console in BOTH Windows and Linux using C++
cprogramming.com
About gotoxy
As mentioned in Michał Trybus's Answer.
About cprintf
I Referred many links, but not getting the simple answers. Me too waiting for the answers for this.
But,In my experience whenever I want the output to be in some colored format , I will use graphics.h, though it is not required.That's why I doesn't had this question in my mind ever before.
You may find this link useful...
codeguru.com
About getch
I think you may already know about this. Instead of getch() in conio.h(not in ansi standard), you can use getchar() in stdio.h.

Just, I was answering the same questions in another thread:
void gotoxy(int x, int y) {
printf("%c[%d;%df",0x1B, y, x);
}
void clrscr(void) {
fprintf(stdout, "\033[2J\033[0;0f");
fflush(stdout);
}
void textcolor(int attr, int fg, int bg) {
printf("%c[%d;%d;%dm", 0x1B, attr, fg + 30, bg + 40);
}
Easy way to do it!

Related

ncurses.h extended characters not displaying properly in c

I am trying to pretty up my program by using ncurses extended characters. However, some of them show up as the question mark in a box: ⍰. This happens when I try functions such as:
addch(ACS_S1);
addch(ACS_LANTERN);
addch(ACS_S3);
And so on. Any help would be appreciated.
#include <ncurses.h>
int main()
{
initscr();
addch(ACS_S1);
addch(ACS_S3);
addch(ACS_S7);
addch(ACS_S9);
addch(ACS_LANTERN);
refresh();
getch();
endwin();
return 0;
}
edit: I forgot to add the code example. So I added it this time
edit: I am using Ubuntu to compile my code
You forgot to tell ncurses what the locale is (and if you did not compile/link with ncursesw, there are still some limitations):
The library uses the locale which the calling program has initialized.
That is normally done with setlocale:
setlocale(LC_ALL, "");
If the locale is not initialized, the library assumes that characters
are printable as in ISO-8859-1, to work with certain legacy programs.
You should initialize the locale and not rely on specific details of
the library when the locale has not been setup.

Which gotoxy() function should I use?

during this year in school my teacher showed us this function:
#include<Windows.h>
void gotoxy(int x,int y)
{
COORD punto;punto.X=x;punto.Y=y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),punto);
}
And looking in here some posts I read about this one based on ANSI escape codes
#include<stdio.h>
void gotoxy(int x, int y)
{
// <ESC>[(ROW);(COLUMN)f
printf("\x1B[%i;%if",y,x);
}
I kind of like the second one more, I feel I understand it better. But I wanted to ask here which of them is better because I know I'm probably missing something. What do you think?
If you write code for Windows then definitely use the first version. It always works on Windows but it does not work on other OSes (it does not even compile because other OSes do not provide these functions).
The second version is not tight to an OS. It works on any OS as long as the application runs in a terminal emulator that understands ANSI escape codes (most of them do).

Linux C console application not using previous command on "keyup"

I've got the following issue:
int main(int argc, char **argv){
while(1){
char command[25];
scanf(" %25[^\n]s", command);
printf("Command '%s'\n", command);
}
return 0;
}
Now whenever I type something in the console it prints me a message with what I just typed.
But if I use the arrow up key to get the last command out of the memory, the command being sent is
^[[A
Which results in the cursor being moved up by the program.
Now how do I fix this?
I want that the last command from memory is triggered.
Thanks in advance!
This is actually pretty non-trivial thing you are asking for. Luckily, there is a library to fix it: GNU Readline library. Be aware about its licensing, though. Last I heard, it's actual GPL and therefore your own program needs to be that, too, if you use it. NetBSD has a library called libedit, which seems to claim to do much of the same thing with less restrictive license.
Here are some more help with readline: https://eli.thegreenplace.net/2016/basics-of-using-the-readline-library/
And if you can stomach the idea of not integrating it directly into your own program, there is a handy utility program called rlwrap, which provides the end-user at least some of the goodness transparently.

Why does mingw-gcc allow getch() to be used unconditionally?

I recently started porting a TON of my C programs to a Windows environment, from my previous Linux development PC. I noticed something a bit off about mingw's Windows GCC implementation.
In Windows, I found a lovely function called getch. It's easy, it's immediate... and it's also non-standard.
I'd like to focus of the "non-standard" part of it. Specifically, I want to know why mingw-gcc allows me to use it, without using anything but the standard libraries.
Assume we have a program that prints "Hello, World!", a NL and CR, and then waits for a key and a return:
#include <stdio.h>
int main(void)
{
char str[14] = "Hello, World!"; //13 characters and a terminator
printf("%s\n\r", str);
scanf("%c");
return 0;
}
Now, let's change a bit of that program to use getch:
#include <stdio.h>
int main(void)
{
char str[14] = "Hello, World!"; //Again, 13 characters and a terminator
printf("%s\n\r", str);
getch(); //See? now it uses getch.
return 0;
}
The interesting part is, Isn't getch a call made by the conio.h library for old DOS/Win32 environments? The compiler doesn't even give a warning. Why does this work?
Here's something I find even a bit more unsettling:
int main(void) //literally NOTHING included
{
getch();
return 0;
}
What on earth? I know for a fact that getch does not exist on Linux environments (natively, anyways). So, where is the compiler getting this call from?
My best guess (please correct me if I am wrong) is that the decision to link whatever has getch is made at link time, not compile time.
In any case, this seems a little odd to me. Why does an implementation of GCC automatically include clearly non-standard capability on Windows?
The compilation step works (though it should produce a warning) because, traditionally, C allows you to call functions that haven't been declared, provided that they return an int which getch() does.
The linking step works because the C runtime library that MinGW uses is a single library, i.e., it provides all the Visual C runtime library functions, including the non-standard ones. MinGW presumably links with it by default because (apart from very rare edge cases) it is always needed, even if all you want is a main() function that does nothing. :-)
It should also be mentioned that the library in question does not officially support third-party use, except by applications built in Visual Studio 6. The more modern runtimes have deprecated getch in favour of the equivalent but standards compliant _getch, but VS6 predates that change.
The compile step will probably 'work' because compilers (at least older versions of compilers — we know that Visual Studio is not up to date with the latest C standards) will assume the return type and the parameters are all int.
The link step will need the appropriate library linked in.

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