简体   繁体   English

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

[英]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). 我有一个程序,接受字符并将它们读入有限大小的缓冲区(在本例中为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. 如果用户输入的字符超过64个,则必须拒绝整个输入字符串,警告用户输入的字符过多,然后重新开始。 If the user hits ctrl-D , which is an end-of-file, the program must exit. 如果用户点击ctrl-D (文件结尾),则程序必须退出。

So my design is as follows: make the actual underlying buffer 65 characters to accomodate for the newline character. 因此,我的设计如下:将实际的基础缓冲区设置为65个字符以适应换行符。 If the final character is not a newline, then the user hit ctrl-D , so the program exits. 如果最后一个字符不是换行符,则用户按ctrl-D ,程序退出。 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). 如果缓冲区已满(即包含65个字符),而最后一个不是换行符,则程序会假定给出了太多字符,因此它将进入循环并不断将输入读入缓冲区,直到缓冲区读取为止in以换行符结尾(在这种情况下,它会警告用户限制并重新开始),或者将其缩短而不会以换行符结尾(在这种情况下,程序将终止)。

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 ? 我的问题是,我该如何处理用户准确输入65个字符(或65的某个整数倍),然后按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 ? 如何在收到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;
}

Constraint: I can only use the read and write functions, but not anything from <stdio.h> . 约束:我只可以使用readwrite功能,但不能从任何<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. 请注意,读取tty(例如在终端中)与读取例如某些管道不同。 (Pseudo tty -s are a complex topic: some of the line buffering happens in kernel). (伪tty -s是一个复杂的主题:某些行缓冲发生在内核中)。

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. 而且您应该有一些缓冲-您可能read字节数超出了所需的字节数,因此请将多余的字节保留在缓冲区中以备将来使用。

So you should malloc the buffer (and re-allocate it when too small). 因此,您应该malloc缓冲区(并在缓冲区太小时重新分配)。 If you teacher don't allow malloc , implement your own allocator using mmap 如果您的老师不允许使用malloc ,请使用mmap实现自己的分配器

Read carefully the read(2) man page. 仔细阅读read(2)手册页。 Don't forget that it can return -1 on error, 0 on end-of-file, or some count on success. 不要忘记,它可以在错误时返回-1,在文件结束时返回0,或者在成功时有所回报。

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." 如果您的缓冲区限制为65/64字节,则编写“读取/处理或解析文本/读取解析/等”的代码。 loop. 环。

When eventually your code receives a CTRL-D then exec the results of all your parses. 最终,当您的代码收到CTRL-D时,然后执行所有解析的结果。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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