简体   繁体   中英

Limit buffer in read() function

I have to create a program that asks from standard input a string and write in standard error the string previously written. This is my program:

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

 int main() {
    char *buffer = malloc(sizeof(char)*20);
    int len = 0;

    do {
        len = read(STDIN_FILENO, buffer, 20);
        if(len == -1)
            write(STDERR_FILENO, "Error read\n", 10);
        else
            write(STDERR_FILENO, buffer, len);
    } while(strncmp(buffer,"fine\n", 5));

    free(buffer);
    return 0;
}

The code works but I'm not satisfied..there is one problem: The buffer is a 20char but I can insert more than 20 char...why? How I can limit the buffer to only 20 char?

The code works but I'm not satisfied..there is one problem: The buffer is a 20char but I can insert more than 20 char...why?

Because your program can't stop someone inputting more than 20 chars; all it can do is limit that it doesn't overflow the buffer which it already does - read() doesn't read more than the requested bytes. It only appears as if a read() call is reading more than size (20) but acutally read() reads only (upto) 20 chars and the rest is read in the next iteration.

No matter what method you use to read input and/or increase buffer size, this problem of "extra input" is always going to be there. What you can do instead is check if if len is 20 and buffer[19] is not \\n :

   else {
        write(STDERR_FILENO, buffer, len);
        /* Read out the left over chars. */
        if (len == 20 && buffer[19] != '\n') {
            char c;
            do {
                read(STDIN_FILENO, &c, 1); /* left out the error checking */
            } while (c != '\n');
        }

Or increase the buffer size, say, to 512 bytes and then only look at the first 20 bytes that you're interested in.

Note: Add error checking for all read() and write() calls.

You're not allocating enough memory for your buffer. You always need 1 more to store the NUL terminating character. And you also need to remember to add that NUL character to the end of the string read in by read as it won't do it for you.

When you get an error, you should exit the loop.

#define BUF_SIZE (20)
int main() {
    char *buffer = malloc(sizeof(char)*(BUF_SIZE+1));
    int len = 0;

    do {
        len = read(STDIN_FILENO, buffer, BUF_SIZE);
        if(len == -1) {
            write(STDERR_FILENO, "Error read\n", 10);
            break;
        } else {
            buffer[len]='\0';
            write(STDERR_FILENO, buffer, len);
        }
    } while(strncmp(buffer,"fine\n", 5));

    free(buffer);
    return 0;
}

You'll probably also find that the strncmp(buffer,"fine\\n", 5) isn't going to work as you'd need to process the read in string to handle lines of input as read will happily read in multiple lines at a time (assuming they all fit in the buffer size).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM