I have a C code, which prompts users for list of directory name, it just uses plain scanf() to receive the input and proceeds. Now I would like to provide autocomplete for directory names (like bash does). Say user enter /home/a and press TAB - it displays list of available user directories that begins with 'a'.how to achieve this?
scanf is not suitable for any kind of auto-complete or even interactive editing beyond the basic level (essentially just backspace) that the kernel cooked-mode terminal driver provides. If you want to do fancier interactive input, you need to change the terminal modes so you get each key event and process them yourself, or you can use a library like readline that does this for you.
Related
I am trying to code a little console chat-program in C on linux.
So far I coded it in a way that both chatting partners are only able to alternately send/recv, because these function calls are blocking by default.
Now I would like to modify that program, so that both are able to send and receive simultaneously.
The problem that I find is, that once you typed some input to the terminal, I don't know how to output received messages, without messing up the current input line of the terminal.
If there was a way to delete that current input line, you could temporarily save that line, print the new message and put the input line right back.
However, I was not able to find a solution for this problem on the internet.
Is it possible to delete the current input line, and if not, how else could I achieve what I want?
I think you should look into ncurses as Edd said in his comment.
It would allow you to easily manage contents in your terminal window, which sounds like a good idea for your chat program.
All you'd need to do is store your messages in 2 character arrays:
char incoming[MSG_MAX]
and
char outgoing[MSG_MAX]
Then you can output those messages wherever you want in your terminal window, since ncurses allows you to specify x,y coordinates on where to put your text.
Then a simple wrapper for one of ncurses erase() family functions would allow you to delete characters from specify x,y coordinates in your terminal window.
Edit: MSG_MAX is not an actual ncurses macro.
I know how to get the stdout into a file using dup/dup2 system calls, but how do I get the entire output that would be normally shown on my terminal(including the prompt that says my username along with the $ symbol and the current working directory) to a file?
Yes you can, but this may be difficult in many details (depending on your expert level). For the shell to behave normally (I would mean exactly as in a terminal), then it needs to interact with a terminal (special system object). So you need to create a program that behave like a terminal, this what pseudo-terminals devices (/dev) are intended for. Read documentation about this to implement it but roughly, your application should behave like the user so should be connected to the slave side of the pseudo-terminal, and the shell to the master side of the pseudo-terminal. Then you can easily log real inputs made by the user and catch outputs made by the shell.
Can't comment cause of low reputation.
I would say there is no way to do that inside a code in C. Instead, you could use bash for example to redirect everything to a file, and leave the code in C as it is.
In this way you have all the info you want to save: prompt, current directory, call to the program (including flags), and of course the output of the program.
Well, you can do:
-For bash prompt PS1: Echo expanded PS1 (in case you want it expanded, if not there is a simple way to do it just echong PS1)
- For executed command: https://unix.stackexchange.com/questions/169259/how-to-capture-command-line-input-into-logfile-and-execute-it-at-the-same-time
- Standard output and error output: Redirect stderr and stdout in a Bash script
And that's all you want to capture, I think.
Look up the script command in Unix systems. If you want to capture all keyboard and std in/out for a command, use the script executable. If you want to see how it's done, look up the source.
How do I do autofill a text when Tab key is pressed after a period from STDIN using C?
Input would look like,
C:\>autofil.exe Hello
C:\>autofil.exe Hello. ( When I enter a period, it should autofil Hello after the period)
C:\>autofil.exe Hello.World *World is autofilled when period was entered.
Second requirement is if I am at
C:\>autofil.exe Hello.World (And when i press Tab key, `World` should print with other suggestions, as `Friend`, and if I press Tab again, print `Matt`, and scroll so on when tab is pressed... )
Well, that is my requirement. Tab complete to autofill text. Also, want to know how to read the Tab key from STDIN.
Thanks!
You could use Readline GNU library For Windows, is pretty easy to use, the other way around is to use PDcurses/Ncurses (are almost the same) and do it by hand (handling console behavior and such).
In case you use readline, to acomplish autocomplete is as simple as doing:
rl_bind_key('\t', rl_complete);
char *input = readline("C:\>");
In case you use Ncurses/PDcurses, you will have to do a little more work :)
First you save actual console parameters.
Then you set echo of the input off with noecho().
You will have to handle input and parse the arguments to call programs.
Also you will have to search in dirs (current and the ones on PATH variable) for things matching your current input.
Before ending your program set again the saved console parameters.
Ncurses How-To Is an easy right to the point guide.
Posix curses definition Contains functions and key definitions.
I have this program in C that reads the input like this:
cod1 = getch ();
if (kbhit())
cod2 = getch ();
I can read every Ctrl+Char possible sequences, except for Ctrl+C, that closes the program - that is OK, and Ctrl+S, that simple is not catch. But I wanted to make Ctrl+S to be the save function in my program; how could I do that? Furthermore, is it possible to read Alt+Char characters? Because it reads it as a regular character, e.g., Alt+A is read with the same codes as A.
Your problem is that input probably gets eaten by terminal emulator.
For example Alt+<Whatever> is often reserved for menu shortcuts (e.g. Alt+F opens File menu). Matching characters are often hilighted once you hold Alt (F get's underscored in File).
Ctrl+S is reserved for Stops all output on screen (XOFF) (again your terminal emulator does that).
As for using Alt+<...> as shortcuts in your command line application. As far as I'm concerned holding Alt doesn't affect character received, it just sets flags which are hard to access in console. Even in GUI application (in Windows) it's quite tricky and you have to use function like GetAsyncState() to check whether alt was pressed.
I think this is simple, but not for me obviously!
I have a console-application. I need to read input from the keyboard, but stdin has been redirected to a file. So how do I create a FILE-Handle that points at the keyboard-stream which i can use with fgets etc.?
I found out that ttyname(0) seems to be what i look for in a POSIX-environment, which I don't have here. I'm in a Windows-system with standard Visual Studio compiler.
Any ideas? Thank you in advance.
There's no easy/portable way to tell if a keyboard exists (your application may be being run from a terminal emulator from a serial port, a telnet session or anything else). If a keyboard actually does exist (including a picture of a keyboard on a touch screen), then you can't really tell how many layers of software the keystrokes need to pass through before they get to your application (e.g. keystrokes might go from a keyboard driver to an input method editor to a GUI to a shell to your application). This means that attempting to get keystrokes directly from a keyboard driver or something is a bad idea that will fail in almost all cases.
The best way to solve your problem is to find out which series of design failures led to STDIN being redirected in the first place.
For example; maybe the application should've had a command line option to read some data from a file; so that the application can get some data from the file and some from STDIN (and get all data from STDIN if the command line option isn't present).
Pulling from the dim dark days of DOS programming here: try opening "CON:" (Console), a reserved word. Hopefully it will open the same way in Windows. The colon may or may not be required. Both "dir >con:" and "dir >con" still work in command prompt.
Also, be sure to use something from the setbuf() family on the output handle to avoid buffering... it's not supposed to buffer terminal I/O, but it never hurts to be sure.
Again, not sure, but I suspect opening separate FILE *conin, *conout for output and one for input may help if you seem to have troubles with one handle doing both input and output.