detect EOF in readline() C - c

I read commands for my program using readline() (I only can use readline()) and I need to exit the program if I enter ctrl-d (EOF). When the line is empty and I enter ctrl-d, EOF is detected and NULL is returned so I can exit the shell. But when the line is not empty, readline man contains that "it is treated as a new line", and I don´t see nothing happens.
I haven´t found more information about EOF in readline.

Related

How to provide an input to my code in order to test it?

I am trying to learn the C language by following K&R2 reference book.
I wrote a program to count how many spaces, tabs and newlines are contained in a given input. (exercise 1-8 p.20)
How can I provide to this program input to test my code ?
#include<stdio.h>
main(){
int c,ne,nt,nf;
ne = 0;
nt = 0;
nf = 0;
while((c = getchar())!=EOF){
if (c == ' '){
ne++;
}if (c== '\t'){
nt++;
}if (c== '\n'){
nf++;
}
}
printf("Input contains %d spaces, %d tabs and %d newlines.",ne,nt,nf);
}
It depends on how you're running your program.
If you're running it from the command line, the program's standard input (which is where getchar reads from) is basically your keyboard, so you can just start typing.
If you're running under an IDE, it can create a new "terminal window" for your program to run in, and for you to type input in. At least for learning, such a terminal window ought to be the default, although unfortunately it seems that sometimes you have to take additional, nonobvious steps to set this up so that it will work.
When you're typing input on your keyboard, you also need a way of saying when you're done typing. You do this by typing a "control character". Under Unix, Linux, and MacOS it's control-D, and under Windows it's control-Z. (See also notes below.)
On a suitably powerful command line, you may also have various input redirection options available to you, such as reading input from a file by involving
./myprogram < filename
or taking some other program's output and "piping" it to your programs input by invoking something like
otherprogram | ./myprogram
A few more notes about control-D and control-Z:
On Unix, Linux, and MacOS, you either have to make sure you're typing the control-D at the beginning of a line (that is, you have to type Enter, then control-D), or if you're not at the beginning of a line, you have to hit control-D twice.
On Windows, you have to hit control-Z, then hit Enter.
(Computers can be so fussy sometimes! :-) )
Also, you should know that although typing control-D or control-Z indirectly results in an EOF value eventually squirting out as getchar's return value in your C program, you will not find that the macro EOF has a value of "control D" or "control Z". EOF is usually the value -1, and the process of turning a control character typed by you on the keyboard, into an EOF value returned by getchar in a C program, is actually a rather elaborate one.
[I've written several long writeups on that "rather elaborate process", but I can't seem to find any of them just now. If you're curious, check back in a couple days, and maybe I'll have found one, or written a new one.]

How to quited the git bash when Re-direct as output?

Today I have the problem about how to quit the git bash input.
The book wrote press Ctrl+D(UNIX) or Ctrl+Z(DOS) in the new line.
I try it but failed.
So I just ask the command to quit it.
Your program is written so that it quits when you enter '#' into the terminal. It cannot detect end of file because that would require a different condition. (You would have to test for EOF, and in addition declare the variable ch as int because that is the actual return value from getchar() and because EOF is usually defined as -1.)

getchar does not return even though buffering is turned off

I compile and run this simple program in console of Linux 3.12, GCC 4.8:
#include <stdio.h>
main() {
setvbuf(stdin, NULL, _IONBF, 0);
printf("%c\n", getchar());
}
Run the program and press any letter, the program does not exit unless I press enter key.
What is stopping getchar() from functioning? Is there a hidden buffer somewhere?
The problem is that your terminal is buffering the input. Until your terminal sends passes the input that it receives along, your program can't see it -- and by default, it doesn't pass it through until it sees a newline.
If you're running bash on Linux, running stty -icanon should change your terminal settings to pass all input through directly without requiring newlines.
The terminal is performing the buffering. A terminal doesn't actually write the line to the standard input of the foreground program until you hit enter.
To see the program do what you're expecting, you can just run echo 'a' | ./myprog. It will immediately exit and print the single character.

Read input directly if input from pipe is invalid

If I receive invalid input from pipe i.e.
echo -1 | my_command
my_command is my C program and I can modify it. Is there any way to prompt the user to enter valid input, i.e. changing the input stream from pipe to stdin?
Thanks in advance.
stdin is the pipe, what you mean is probably open the console instead. That's certainly possible:
freopen("/dev/tty", "r", stdin);
(This should work on any Unix-style platform. Be sure to check for errors, as always.)

C stdin reads file infinitely

I have a basic C program that needs to read input from stdin.
First, it reads from an input file by using
./Program <input
and then it loops through to read that until there's no more
while(scanf("%s",command)!=EOF){
printf("%s\n",command);
}
After that I need to read from the keyboard again, but it continues infinitely to spam read the last line from my input file, not letting me use my keyboard for input.
while(1){
scanf("%s",command);
if(!strcasecmp(command,"exit"))
exitProg();
else if(!strcasecmp(command,"help"))
helpMess();
else
printf("Command \"%s\" not recognized, use command \"help\" for a list.\n",command);
}
Read the documentation for scanf, specifically the part about the return value, excerpted below:
Return Value
On success, the function returns the number of items successfully read. This count can match the expected number of readings or fewer, even zero, if a matching failure happens.
In the case of an input failure before any data could be successfully read, EOF is returned.
The problem you're having is that once the file runs out of data, the program's standard-in does not revert back to the controlling terminal, it stays at the end of the empty file. Your scanf call is silently failing, leaving the contents of command unmodified. If you want to be able to read from both, you'd need to find another way of handling that.
It might be possible that your shell supports this functionality.

Resources