1

I am trying to loop over stdin, but since we cannot know the length of stdin, I am not sure how to create the loop or what condition to use in it.

Basically my program will be piped in some data. Each line in the data contains 10 characters of data, followed by a line break (So 11 characters per line)

In pseudocode, what I am trying to accomplish is:

while stdin has data:
    read 11 characters from stdin
    save 10 of those characters in an array
    run some code processing the data
endwhile

Each loop of the while loop rewrites the data into the same 10 bytes of data.

So far, I have figured out that

char temp[11];
read(0,temp,10);
temp[10]='\0';
printf("%s",temp);

will take the first 11 characters from stdin,and save it. The printf will later be replaced by more code that analyzes the data. But I don't know how to encapsulate this functionality in a loop that will process all my data from stdin.

I have tried

while(!feof(stdin)){
    char temp[11];
    read(0,temp,11);
    temp[10]='\0';
    printf("%s\n",temp);
}

but when this gets to the last line, it keeps repeatedly printing it out without terminating. Any guidance would be appreciated.

quantumbutterfly
  • 1,815
  • 4
  • 23
  • 38
  • 4
    You are mixing buffered and non-buffered I/O (read() is non-buffered, so feof( apparently never triggers). Try fread(). Also: Test your return values! What does read() return? – Peter - Reinstate Monica Feb 06 '16 at 18:14
  • 1
    You may also be interested in this question: http://stackoverflow.com/questions/5431941/why-is-while-feof-file-always-wrong. In a nutshell: the end of file condition is only detected during the attempt to read; the loop must be left in that case after the read, because the buffer does not contain meaningful data. – Peter - Reinstate Monica Feb 06 '16 at 18:16
  • See [`while (!feof(stdin))` is always wrong](http://stackoverflow.com/questions/5431941/while-feof-file-is-always-wrong) for a discussion of why you don't write your loop like that. Additionally, you're reading from file descriptor 0, so the standard I/O functions won't know whether you've reached EOF or not. Test the return result from `read()`; it tells you how many characters it read. It returns 0 on EOF and -1 on other errors. Which, apart from the URL, is much the same as what Peter A Schneider wrote. You might do better with `fgets()` or `fread()`. It depends, in part, on the data. – Jonathan Leffler Feb 06 '16 at 18:25
  • Thanks! I didn't realize read() returns a value – quantumbutterfly Feb 06 '16 at 18:38

1 Answers1

2

Since you mention line breaks, I assume your data is text. Here is one way, when you know the line lengths. fgets reads the newline too, but that is easily ignored. Instead of trying to use feof I simply check the return value from fgets.

#include <stdio.h>

int main(void) {
    char str[16];
    int i;
    while(fgets(str, sizeof str, stdin) != NULL) {  // reads newline too
        i = 0;
        while (str[i] >= ' ') {                     // shortcut to testing newline and nul
            printf("%d ", str[i]);                  // print char value
            i++;
        }
        printf ("\n");
        str[i] = '\0';                              // truncate the array
    }
    return 0;
}

Program session (ended by Ctrl-Z in Windows console, Ctrl-D in Linux)

qwertyuiop
113 119 101 114 116 121 117 105 111 112
asdfghjkl;
97 115 100 102 103 104 106 107 108 59
zxcvbnm,./
122 120 99 118 98 110 109 44 46 47
^Z
Weather Vane
  • 33,872
  • 7
  • 36
  • 56