How to set a interface in terminal using termcap library - c

I need to create a interface in terminal using the termios.h in C. To keep it short I have to create a executable like ./exec and after I run, it has to stop displaying the PS1 variable.
If I have a program which displays the following text Hello World that uses printf it will look like:
$:> ./exec
Hello World!
But instead of printing that, I need only the Hello World! to be in the terminal, like when you clear the screen while the program is displaying.
Hello World!
To say it in other way, the purpose is to clean the terminal, and when the ./exec is runned, it should clear this line as well, $:> ./exec.
So far I managed to make this function
void clear_screen()
{
char buf[1024];
char *str;
tgetent(buf, getenv("TERM"));
str = tgetstr("cl", NULL);
fputs(str, stdout);
}
Which clears the screen but it keeps the line with the command itself $:> ./exec. I am not allowed to use ncurses.h library.
Here is a main:
int main(void)
{
clear_screen();
printf("Hello World!\n");
return (0);
}

Something was omitted from the question (and it confuses termcap with termios). Since the sample code uses termcap, answers should address that. To recap, here's a complete example:
#include <stdio.h>
#include <stdlib.h>
#include <termcap.h> /* this comes from ncurses, anyway... */
static void clear_screen(void)
{
char buf[1024];
char *str;
tgetent(buf, getenv("TERM"));
str = tgetstr("cl", NULL);
fputs(str, stdout);
}
int main(void)
{
clear_screen();
printf("Hello World!\n");
return (0);
}
The "cl" capability is what matters. It is defined as the corresponding feature to terminfo clear:
clear_screen clear cl clear screen and
home cursor (P*)
If you run that example from the command-line with a correctly written terminal description, the output does this:
clear the entire display,
move the cursor to the home-position
print a message (which would be on the first line of the screen)
exit
After that, the shell prints its prompt again.
There's a couple of problems with the example:
it is using fputs for output. terminfo/termcap data could include padding, which won't work with that. You won't notice that with common terminal emulators' terminal description, but it matters for hardware terminals. The vt100 termcap would have this, for instance (the "50" is padding):
:cl=50\E[H\E[J:
The proper function to use would be tputs. It happens to be in an overlapping set of functions between termcap and terminfo. In ncurses, the complete description is in the terminfo manual page.
some terminals (Microsoft telnet used to be a good example, though no one's tested recently...) didn't treat the control sequence properly. IN the previous example, one might have used
:cl=\E[J\E[H
to demonstrate this: the terminal didn't clear the whole screen, but only the remainder. To work around this, the terminal descriptions were modified to move the cursor first.

printf("\033[2J"); // clear screen
printf("\033[H"); // cursor home
If you want to do anything with the screen, this is one way. You can look up other codes from 'some programmer dude's comment. You can also google vt100 codes.
There are libraries that abstract this like Ncurses but since you can't use that (why?) that's out - I'll let others elaborate on that though, maybe there are others that are allowed..
edit
try this:
printf("\033[1A\r\033[2K");
See my comment.
the VT100 codes don't help either
If you want to do anything with the screen vt100 codes are like a hacker's dream come true. Run, if you see the DEA coming, they are that good.

Related

how do I remove the scanned number from the terminal so that I can't see it?

I am trying to create a minigame to play with my friends, where someone puts a number, and then we have 10 tries to guess it. Unfortunately, we a number is scanned, it stays in the terminal, so everyone can read and cheat.
I also tried to do something kinda dumb, which was use printf("\n\n\n\n\n\n\n\n\n\n\n\n\n...") with 29, but that way the code goes down and looks bad.
Can anyone help me?
You didn't specify the platform (OS).
In General there are several methods:
Supressing echo via stty(): See https://stackoverflow.com/a/67709009/6607497
Using getpass() (obsolete)
Use terminal escape sequences (like ANSI) to Query the input at a specific line, then erase that line. See https://en.wikipedia.org/wiki/ANSI_escape_code for details.
Learn to use curses. See http://heather.cs.ucdavis.edu/~matloff/UnixAndC/CLanguage/Curses.pdf for details
How to disable echo in windows console?
ANSI C No-echo keyboard input
https://www.reddit.com/r/C_Programming/comments/64524q/turning_off_echo_in_terminal_using_c/
https://social.msdn.microsoft.com/Forums/en-US/14220ac4-a557-4cea-b29d-f46222a36ef5/how-to-not-echo-the-input-of-consoleread
http://www.cplusplus.com/forum/general/3570/
https://falsinsoft.blogspot.com/2014/05/disable-terminal-echo-in-linux.html
...
Maybe you should have searched elsewhere first!
Probably the simplest thing (but certainly not the best)you can do is shell out to stty to manipulate the terminal database. Eg:
#include <stdio.h>
#include <stdlib.h>
int
main(void)
{
char b[32];
printf("prompt: ");
system("stty -echo"); /* Turn off echo */
if( scanf("%31s", b) == 1 ){
printf("\nyou entered %s\n", b);
}
system("stty echo"); /* Turn echo back on */
return 0;
}
Note that this does not handle signals well, and your terminal may end up with a modified state.
If you use windows, you can specifies the maximum number of commands in the history buffer.:
system("doskey /listsize = 0");
In addition, You can simulate the keyboard shortcut ALT+F7 to clear the history.
See more for windows.
If you use Unix, you can clean the history:
system("history -c");
if you #include <stdlib.h>, system("cls"); should clear the terminal after the number is entered. I tried the game, its fun!

Get highlighted text & open program with it (replicate clipboard.exe behavior)

Is it possible to highlight text with your cursor in any program, like you do with str+c and start a tool with the highlighted text as argument?
As far as I know, in Linux as well as in Windows, one can call a script/program with a custom shortcut. I assume str+c just does the same, calling a little program with the highlighted text as argument. How to replicate this?
For demonstration purposes, let's take this C - program printing the value it was called with:
#include <stdio.h>
int main(int argc, char**argv){
if(argc == 2){
printf("program called with: '%s'\n", argv[1]);
}
}
Can one type the text "HelloWorld" in Word for example, highlight it, and press something like str+alt+p, calling
someprogram.exe HelloWorld
or as for Linux
someprogram HelloWorld
I am really curious if this is possible.
Edit: I'm interested to know, how to replicate the clipboard.exe functionality. I have written a program "write_custom.exe" storing anything given as argument (argv[1]) in a text-file, after deleting it's previous content. Other programs can read the content of this text-file and so are able to use this custom clipboard. It's purpose is mainly for self-teaching.
As I am at the beginning of my codeing career, I only know C, but I am open for solutions in other languages as well. My goal is to run this write_custom.exe, with highlighted text as argument, on my computer and my Linux-VM.
You might want to check out ncurses (Linux) and Console API (Windows). The code will not be cross-platform, but you can pretty easily write some code to make them share some basic behavior :).

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);

How can I see an the output of my C programs using Dev-C++?

I'm looking to follow along with The C Programming Language (Second Addition) on a machine running Vista.
So far, I've found Dev-C++ the easiest IDE to do this in. However, I still have one problem. Whenever I run my compiled code, for example: a simple hello world program, it runs, but the console window just flickers on the screen, and I can't see the output.
How can I see an the output of my C programs using Dev-C++? I found a C++ specific solution, System("pause"), and a really ugly C solution, while looping fflush(stdout), but nothing nice and pretty.
I put a getchar() at the end of my programs as a simple "pause-method". Depending on your particular details, investigate getchar, getch, or getc
In Windows when a process terminates, the OS closes the associated window. This happens with all programs (and is generally desirable behaviour), but people never cease to be surprised when it happens to the ones they write themselves.
I am being slightly harsh perhaps; many IDE's execute the user's process in a shell as a child process, so that it does not own the window so it won't close when the process terminates. Although this would be trivial, Dev-C++ does not do that.
Be aware that when Dev-C++ was popular, this question appeard at least twice a day on Dev-C++'s own forum on Sourceforge. For that reason the forum has a "Read First" thread that provides a suggested solution amongst solutions to many other common problems. You should read it here.
Note that Dev-C++ is somewhat old and no longer actively maintained. It suffers most significantly from an almost unusable and very limited debugger integration. Traffic on the Dev-C++ forum has been dropping off since the release of VC++ 2005 Express, and is now down to a two or three posts a week rather than the 10 or so a day it had in 2005. All this suggest that you should consider an alternative tool IMO.
Use #include conio.h
Then add getch(); before return 0;
The easiest thing to do is to run your program directly instead of through the IDE. Open a command prompt (Start->Run->Cmd.exe->Enter), cd to the folder where your project is, and run the program from there. That way, when the program exits, the prompt window sticks around and you can read all of the output.
Alternatively, you can also re-direct standard output to a file, but that's probably not what you are going for here.
For Dev-C++, the bits you need to add are:-
At the Beginning
#include <stdlib.h>
And at the point you want it to stop - i.e. before at the end of the program, but before the final }
system("PAUSE");
It will then ask you to "Press any key to continue..."
Add this to your header file #include
and then in the end add this line : getch();
You can open a command prompt (Start -> Run -> cmd, use the cd command to change directories) and call your program from there, or add a getchar() call at the end of the program, which will wait until you press Enter. In Windows, you can also use system("pause"), which will display a "Press enter to continue..." (or something like that) message.
Add a line getchar(); or system("pause"); before your return 0; in main function.
It will work for you.
;
It works...
#include <iostream>
using namespace std;
int main ()
{
int x,y; // (Or whatever variable you want you can)
your required process syntax type here then;
cout << result
(or your required output result statement); use without space in getchar and other syntax.
getchar();
}
Now you can save your file with .cpp extension and use ctrl + f 9 to compile and then use ctrl + f 10 to execute the program.
It will show you the output window and it will not vanish with a second Until you click enter to close the output window.
i think you should link your project in console mode
just press Ctrl+h and in General tab select console.
When a program is not showing or displaying an output on the screen, using system("pause"); is the solution to it on a Windows profile.
The use of line system("PAUSE") will fix that problem and also include the pre processor directory #include<stdlib.h>.
Well when you are writing a c program and want the output log to stay instead of flickering away you only need to import the stdlib.h header file and type "system("PAUSE");" at the place you want the output screen to halt.Look at the example here.The following simple c program prints the product of 5 and 6 i.e 30 to the output window and halts the output window.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int a,b,c;
a=5;b=6;
c=a*b;
printf("%d",c);
system("PAUSE");
return 0;
}
Hope this helped.

Resources