将字符读入有限的缓冲区大小

时间:2013-08-11 06:08:43

标签: c input system-calls

我有一个程序,它接收字符并将它们读入有限大小的缓冲区(在本例中为64)。如果用户输入的字符超过64个,则必须拒绝整个输入字符串,警告用户输入了太多字符,然后重新开始。如果用户点击ctrl-D(文件结尾),程序必须退出。

所以我的设计如下:使实际的底层缓冲区为65个字符,以适应换行符。如果最终字符不是换行符,则用户点击ctrl-D,程序退出。如果缓冲区被填充(即它包含65个字符)并且最后一个不是换行符,则程序假定给出了太多字符,因此它进入循环并不断地将输入读入缓冲区,直到读取缓冲区为止以换行结束(在这种情况下它会警告用户限制并重新开始),或者它被缩短而不以换行符结束(在这种情况下程序终止)。

我的问题是,如何处理用户输入正好65个字符(或65的某个整数倍),然后点击ctrl-D的情况?正如程序当前所示,当缓冲区被填充并且不以换行符结束时,它假定存在溢出,但在这种情况下我希望程序终止。如何在收到65个字符的标量倍数然后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;
}

约束:我只能使用readwrite函数,但不能使用<stdio.h>中的任何函数。

2 个答案:

答案 0 :(得分:0)

你应该接受任意大小的线条。请注意,阅读tty -e.g.在终端中 - 与阅读不同一些管道。 (伪tty - s是一个复杂的主题:一些行缓冲发生在内核中。

你应该有一些缓冲 - 你通常可以比你需要的多read个字节,所以在缓冲区中保留额外的字节以备将来消费。

所以你应该malloc缓冲区(当它太小时重新分配它)。如果您的老师不允许malloc,请使用mmap

实施您自己的分配器

仔细阅读read(2)手册页。不要忘记它可以在出错时返回-1,在文件结束时返回0,或者在成功时返回一些。

答案 1 :(得分:-3)

如果这真的是一个shell,为什么不处理更长的数据输入流?

如果您的缓冲区限制为65/64字节,则编码&#34;读取/处理或解析文本/读取解析/等。&#34;循环。

当你的代码最终收到CTRL-D时,然后执行所有解析的结果。