I want to be able to do this:
$ echo "hello world" | ./my-c-program
piped input: >>hello world<<
I know that isatty
should be used to detect if stdin is a tty or not. If it’s not a tty, I want to read out the piped contents — in the above example, that’s the string hello world
.
What’s the recommended way of doing this in C?
Here’s what I got so far:
#include <stdio.h>
#include <unistd.h>
int main(int argc, char* argv[]) {
if (!isatty(fileno(stdin))) {
int i = 0;
char pipe[65536];
while(-1 != (pipe[i++] = getchar()));
fprintf(stdout, "piped content: >>%s<<\n", pipe);
}
}
I compiled this using:
gcc -o my-c-program my-c-program.c
It almost works, except it always seems to add a U+FFFD REPLACEMENT CHARACTER and a newline (I do understand the newline though) at the end of the piped content string. Why does this happen, and how can this issue be avoided?
echo "hello world" | ./my-c-program
piped content: >>hello world
�<<
Disclaimer: I have no experience with C whatsoever. Please go easy on me.
The replacement symbol shows up because you forgot to NUL-terminate the string.
The newline is there because by default, echo
inserts '\n'
at the end of its output.
If you want to not insert '\n'
use this:
echo -n "test" | ./my-c-program
And to remove the wrong character insert
pipe[i-1] = '\0';
before printing the text.
Note that you need to use i-1
as the null character because the way you implemented your loop test. In you code i
is incremented once more after the last char.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With