Search code examples
cinputbufferstdinstdio

Reading From Stdin Twice in C


    int getLineCount() {
        int ret = 0;
        char c;
        while ((c = fgetc(stdin)) != EOF)
            if (c == '\n')
                ret++;
        return ret + 1;
    }

    void fill(char *WORD) {
        int charIndex = 0;
        char c;
        while ((c = fgetc(stdin)) != EOF) {
           *(WORD + charIndex++) = c;
        }
    }

    int main() {
        int lineNum = getLineCount();
        char *WORD = (char*)calloc(lineNum * 18,sizeof(int));

        fill(WORD);
        return 0;
    }

Here is the part of my code, and my question is(as you can see):

I'm trying to read stdin's content twice, but after the getLineCount function, it stays at the EOF and I can't read it again in fill function.

Im taking stdin from the user with this command in Linux;

$./output < text_file.txt

Is there any way to roll back stdin to starting character? If not, how can I fix this problem?

Thanks.


Solution

  • You can use rewind(stdin) to set the stream back to the start of file, but be aware that it is not guaranteed to work, especially if the stream is a pipe, a terminal or a device.

    Your allocation scheme is incorrect: you could compute the size of the file and then allocate that many bytes, but your current (char*)calloc(lineNum * 18,sizeof(int)); allocates 18 times the size of type int for each line. Some files with short lines will fit in this array while others will invoke undefined behavior.

    Note that c must be defined as int for c = fgetc(stdin); to properly store all values including the EOF special value.