简体   繁体   中英

Reading characters into a limited buffer size

I have a program that takes in characters and reads them into a buffer of limited size (in this case 64). If the user enters more than 64 characters, it must reject the entire input string, warn the user that they entered too many characters, and start over. If the user hits ctrl-D , which is an end-of-file, the program must exit.

So my design is as follows: make the actual underlying buffer 65 characters to accomodate for the newline character. If the final character is not a newline, then the user hit ctrl-D , so the program exits. If the buffer is filled (ie it contains 65 characters) and the final one isn't a newline, the program assumes that too many characters were given, so it goes into a loop and continually reads input into the buffer until it the buffer read in ends with a newline (in which case it warns the user of the limit and starts over), or it's cut short without ending in a newline (in which case the program terminates).

My question is, how can I handle the case where the user enters exactly 65 characters (or some integer multiple of 65), and then hits ctrl-D ? As the program currently stands, when the buffer is filled and doesn't end in a newline, it assumes there was an overflow, but in this case I would like the program to terminate. How can I make the program terminate upon receiving a scalar multiple of 65 characters and then a ctrl-D ?

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

#define BUFSIZE ( 65 )


int main( int argc, char* argv[] ) {
    char* prompt = "myshell->";
    char* tooMany = "Max characters (64) exceeded.\n";
    int numInput;
    int done = 0;
    char input[ BUFSIZE ];
    while( !done ) {
        int cont = 0;

        write( STDOUT_FILENO, prompt, strlen( prompt ) );
        numInput = read( STDIN_FILENO, input, BUFSIZE );
        if( input[ numInput - 1 ] == '\n' ) {
            cont = 1;
        } else {
            if( numInput != BUFSIZE ) {
                done = 1;
                write( STDOUT_FILENO, "\n", strlen( "\n" ) );
            } else {
                int spill = 1;
                while( spill ) {
                    numInput = read( STDIN_FILENO, input, BUFSIZE );
                    if( input[ numInput - 1 ] == '\n' ) {
                        spill = 0;
                        write( STDOUT_FILENO, tooMany, strlen( tooMany ) );
                    } else {
                        if( numInput != BUFSIZE ) {
                            spill = 0;
                            done = 1;
                            write( STDOUT_FILENO, "\n", strlen( "\n" ) );
                        }
                    }
                }
            }
        }

        /*done ingesting input. Now do something with it...*/
        if( cont ) {
            write( STDOUT_FILENO, input, numInput );
        }

    }
    return 0;
}

Constraint: I can only use the read and write functions, but not anything from <stdio.h> .

You should really accept arbitrarily sized lines. Notice that reading a tty -eg in a terminal- is different from reading eg some pipe. (Pseudo tty -s are a complex topic: some of the line buffering happens in kernel).

And you should have some buffering -you could often have read more bytes than what you need, so keep the extra bytes in the buffer for future consumption.

So you should malloc the buffer (and re-allocate it when too small). If you teacher don't allow malloc , implement your own allocator using mmap

Read carefully the read(2) man page. Don't forget that it can return -1 on error, 0 on end-of-file, or some count on success.

If this is really a shell then why not handle longer data entry streams?

If your buffer is limited to 65/64 bytes then code a "read/process or parse text/read parse/etc." loop.

When eventually your code receives a CTRL-D then exec the results of all your parses.

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