Read from stdin in the fastest way in C

Viewed 198

I have to write a program in C in which I have to read some values from stdin and also to do it with the quickest function in C. The stdin is preloaded in a form like this:

int,int\n
char\n
int,int,int\n ex...  

I'm asking for help because scanf is too slow for the time requirement of the project and also because I have some difficulties to read because of the ',' that I don't really need and that causes me problems. I've tried with gets or getchar, but I didn't manage to make it work.

1 Answers

The fastest way to read stdin ("standard in" - 0 file descriptor) is to use read function from <unistd.h.>:

char buff[1024] = {0}; /* zero-initialize */
ssize_t res = read(0, &buff, sizeof(buff));
/* res is amount of bytes read; -1 if error */

Here is an example of program which reads 1024 bytes of stdin and echoes it to stdout (file descriptor: 1) (no error handling for simplicity):

#include <unistd.h>
#define BUFSIZ 1024

int main() {
    char buff[BUFSIZ] = {0}; /* zero-initialize */
    ssize_t nread = read(0, buff, BUFSIZ);
    /* pass amount of bytes read as a byte amount to write */
    write(1, buff, nread);
    return 0;
}

This is the fastest way to read from stdin because read is native libc wrapper for a kernel syscall. By the way, you can use -O3, or even -Ofast compiler options to make it optimize the code.

Also, keep in mind that read and write are not guaranteed to read/write exactly as many bytes as you want, you should call it in a loop like this:

size_t to_write = sizeof(buff); /* example, can be result of read() */
int fd = 1;

size_t nwrote = 0;
while ((nwrote += write(1, buff, to_write) < to_write) {
    /* pointer arithmetic to create offset from buff start */
    write(fd, buff+nwrote, to_write - nwrote);
}
Related