When I use readline function and type control-D to tell my program it reached EOF, ^D
is echoed in the terminal.
I would like to remove it or to replace it by another message.
I tried stty -echoctl
command but it doesn't work.
I'm using ZSH with Oh My Zsh and iTerm2.
# include<stdio.h>
# include<string.h>
# include<stdlib.h>
# include<unistd.h>
# include<sys/types.h>
# include<sys/wait.h>
# include<readline/readline.h>
# include<readline/history.h>
int input(void)
{
char *buf;
buf = readline("Please write the argument:\n");
if (buf == NULL)
{
printf("Quitting the program\n");
exit(0);
}
return (0);
}
int main()
{
while (1)
{
if(!input())
continue;
}
return (0);
}
I don't know what I can try now, I checked lots of Stack Overflow threads and didn't find anything.
CodePudding user response:
Although it looks like you are using the readline library, you're actually using a compatibility layer built on top of the BSD libedit library, which is what is provided by default by Mac OS. So you can expect some things to work a bit differently.
Unfortunately, libedit is not well-documented. It appears to be possible to modify the binding of the Ctrl-D key by creating a file name .editrc
in your home directory, and inserting the line:
bind ^D ed-end-of-file
That will apply the change to all applications which use the libedit
library, which may be a bit drastic. To make it apply only to your program, you can insert the line:
rl_readline_name = "progname";
at the beginning of your program, before the first time you call readline
. Change progname
to whatever you want to use as a tag for your program. Then you can change the editrc
command to the following (using the same tag for progname
):
progname:bind ^D ed-end-of-file
At least, that worked on an Ubuntu system.
Another option would be to just install GNU readline on your Mac. According to the GNU readline home page:
MacOS X users may obtain MacOS X packages for readline-8.0 from MacPorts, readline-7.0 from Fink, or readline-8.0 from Homebrew.
Then you'll have to make sure you build your program with GNU readline instead of the libedit shim.
Doing that will make also make the prompt work the way it reads (i.e., the prompt includes a newline). I don't know if that's what you want, though.
CodePudding user response:
What you need to do is basically to have a function that reads AND manually print every character so that you can intercept characters that shouldn't be printed. Here is an idea to get started:
int ch;
char buf[SIZE] = {0};
char *p = buf;
while(1) {
ch = getchar();
if(ch == EOF) {
p[1] = 0;
break;
}
putchar(ch);
*p = ch;
}
You would probably like to treat backspace '\b'
in a special way. Like decrementing p
, but watch out for going out of bounds.