1
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>


int main(int argc, char **argv) {
    int o;
    int w = 80;
    int p = 1;

    int c;
    int line_count = 0;
    long remember_pos;
    while ((c = getc(stdin)) != EOF) {
        long num = ftell(stdin);
        printf("%li\n", num);
    }
}

Basically processing the standard input when you do it in unix, like for example

$ gcc -Wall fileabove.c
$ echo hello | ./a.out
1
2
3
4
5
6

I want it to process the 'hello' from echo. I want there to be a way to get to stdin[0] (in file's with fseek). Also get the position we are currently on (in file's with ftell)

OR looking for any other way to keep track of unseekable standard input

  • what is `optind` ? – ntshetty Feb 28 '18 at 01:38
  • 2
    Possible duplicate of [Using fseek with a file pointer that points to stdin](https://stackoverflow.com/questions/4917801/using-fseek-with-a-file-pointer-that-points-to-stdin) – lurker Feb 28 '18 at 01:41
  • Simply looking for an equivalent of fseek or ftell for stdin like "echo hello", if it's possible. –  Feb 28 '18 at 01:45
  • @Basbas: As the suggested duplicate shows, there is no such thing. You can repeatedly get characters until you run out, and that's about it. Character streams aren't files; they have no defined end point until the stream is closed (after all, if the user manually typed inputs, rather than using `echo`, it would look roughly the same to your program, and the user may or may not *ever* hit Ctrl-D to signal end of stdin input). – ShadowRanger Feb 28 '18 at 01:46

1 Answers1

2

Since getchar() reads characters from stdin, you can use fseek(stdin) and ftell() on stdin. But calling those functions will always fail when stdin is not a normal file. Look at the link @lurker pointed.

The following code returns -1 and ESPIPE (Illegal Seek)

#include <stdio.h>
#include <errno.h>
main() {
        long pos;
        pos = ftell(stdin);
        printf("%ld\n", pos);
        printf("errno=%d\n", errno);
}

$ ./a.out

However, when we run the same code with file redirection ftell() returns 0 without error. This time stdin of ./a.out is a normal file and seekable.

$ ./a.out < a.c

So the most viable solution to original poster is:

$ echo hello > input.txt
$ ./a.out < input.txt
Chul-Woong Yang
  • 1,223
  • 10
  • 17
  • 1
    "*But it will always fail because `stdin` is not seekable stream.*" Not necessarily. `stdin` can refer to a pipe, terminal, normal file, socket, etc (it's inherited from the calling process). Normal files are seekable. – melpomene Feb 28 '18 at 01:48
  • @melpomene Yes, you are right. I fixed the answer. Thank you. – Chul-Woong Yang Feb 28 '18 at 01:54
  • long num = ftell(stdin) always give's '-1', if it were echo hello | ./a.out? –  Feb 28 '18 at 02:03
  • 1
    if you do `echo hello | ./a.out` then stdin of a.out is not normal file and is not seekable. Try making data file with content `hello` then do `./a.out < data_file` – Chul-Woong Yang Feb 28 '18 at 02:06
  • So there's no way to do ftell(stdin) such that echo hello | ./a.out would work as wanted? –  Feb 28 '18 at 02:09
  • @Basbas As you said, No. – Chul-Woong Yang Feb 28 '18 at 02:12