11

I want to read from a stdin stream. Is there any difference in using read() or fgets() to read from the stdin stream.

I am attaching the following two pieces of code with fgets and read. With fgets I can use a java program to write and read from the c program easily. With read and write my java program hangs waiting for the output from C program which does not come.

I am just reading a line keeping it in buf and appending A to it.

Java program is able to talk to the following program which works with fgets and puts.

#include <stdio.h>
#include <string.h>
#define SIZE  200000
main()
{
int rc;
int df;
int i;
char buf[SIZE];
for(i=0;i<=120000;i++) {
      memset(buf,'\0',SIZE);
      if(!fgets(buf,SIZE-1,stdin))
        continue;
      strcat(buf,"A_A_A_A_A_A_A");
      puts(buf);
}

}

but not with read() and write()

main()
{
int rc;
int df;
int i;
char buf[32768];
rc = fcntl(fileno(stdin), F_SETFL, O_NONBLOCK);
//rc = fcntl(fileno(stdout), F_SETFL, O_NONBLOCK);
FILE *fp;
for (;;) 
{
    int rc=-1;
    memset(buf,'\0',32768);
    //rc = fread(buf,5, 1, stdin);
    rc = read(fileno(stdin),buf,32768); 
    if (rc > 0)
    {
        strcat(buf,"B_B_B_B_B_B_B_B_B");
        write(fileno(stdout),buf,strlen(buf));

    }
}

}

Could some one tell the reason. I am still finding it hard to figure out

Lance Roberts
  • 22,383
  • 32
  • 112
  • 130
ssD
  • 339
  • 2
  • 9
  • 22

5 Answers5

32
  • fgets is a function, read is a system call
  • fgets is standard C, read is not
  • fgets is stdio buffered, read is not
  • fgets works with a FILE *, read works with a file descriptor
  • fgets reads until newline, read reads how much you tell it to
tacaswell
  • 84,579
  • 22
  • 210
  • 199
cnicutar
  • 178,505
  • 25
  • 365
  • 392
  • 6
    `fgets()` appends a null byte to the buffer (which gives `strcat()` a place to start from); `read()` does not. – user207421 Sep 10 '12 at 05:39
8

There is an important alternative (fread) which sits somewhat in the middle, so the question should really be broken into two parts - and both are already well answered in SO:

What is the difference between fread and read?

What is the difference between fgets and fread?

Quick rule of thumb: use fgets if you intend to read textual data line by line, use fread elsewhere.

Community
  • 1
  • 1
leonbloy
  • 73,180
  • 20
  • 142
  • 190
2
#include <stdio.h>
char    fgets (char * restrict str, int size, FILE * restrict stream)

The fgets() function reads at most one less than the number of characters specified by size from the given stream and stores them in the string str. Reading stops when a newline character is found, at end-of-file or error.

Reference: fgets()

#include <unistd.h>
ssize_t pread(int fildes, void *buf, size_t nbyte, off_t offset);

The read() function shall attempt to read nbyte bytes from the file associated with the open file descriptor, fildes, into the buffer pointed to by buf. The behavior of multiple concurrent reads on the same pipe, FIFO, or terminal device is unspecified.

Reference: read()

Andrei Sfat
  • 8,440
  • 5
  • 49
  • 69
  • +1 @Andrei for opengroup (and not cplusplus) ... but you can use the [POSIX.1-2008 Reference](http://pubs.opengroup.org/onlinepubs/9699919799/) rather than POSIX.1-2004 as in your links ;) – pmg Jun 02 '11 at 20:51
  • updated reference links, @pmg. Thank you for correcting my answer. – Andrei Sfat Jun 02 '11 at 20:59
  • @Andrei... based on the above programs I cannot tell the diffrence if I am using fgets to read from *stdin* or read for reading stdin. Similarly puts(buf) helps me read from stdout through an external program and so does write(stdout,buf). but read write are slow then puts gets and puts gets work with external java program...could you help clear this – ssD Jun 03 '11 at 01:41
  • @ssD, how are you calling the c program from java? – Andrei Sfat Jun 03 '11 at 04:37
  • @Andrei I am using Process.getruntime() and then using BufferedWriter and BufferedReader to read and write in the external C program – ssD Jun 03 '11 at 23:50
  • @ssD, have you tried using JNI ( Java Native Interface) ? http://java.sun.com/docs/books/jni/html/jniTOC.html . Maybe there are some issues regarding C system calls from Java. Give it a try with JNI, maybe it will work – Andrei Sfat Jun 04 '11 at 04:48
0

One (read) attempts to read the specified number of bytes, whereas the other (fgets) attempts to read one line and will stop at a newline.

NPE
  • 486,780
  • 108
  • 951
  • 1,012
0

The two functions have nothing in common. read is a POSIX system call, which reads from a file handle. fgets is C library function that reads from a FILE *.