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

C 将字符读入有限的缓冲区大小,c,input,system-calls,C,Input,System Calls,我有一个程序,它接收字符并将它们读入一个大小有限的缓冲区(在本例中为64)。如果用户输入的字符超过64个,则必须拒绝整个输入字符串,警告用户输入的字符过多,然后重新开始。如果用户点击ctrl-D,这是文件的结尾,程序必须退出 因此,我的设计如下:将实际的底层缓冲区设置为65个字符,以适应换行符。如果最后一个字符不是换行符,则用户按ctrl-D键,程序退出。如果缓冲区已填充,即它包含65个字符,而最后一个字符不是换行符,则程序会假定给定的字符太多,因此它会进入循环并持续读取缓冲区中的输入,直到它读

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

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

我的问题是,如何处理用户输入65个字符或65的整数倍,然后点击ctrl-D的情况?正如程序当前所处的状态,当缓冲区被填满并且没有换行结束时,它假定存在溢出,但在这种情况下,我希望程序终止。如何在接收到65个字符的标量倍数和ctrl-D后使程序终止


约束条件:我只能使用读写函数,但不能使用中的任何函数。

如果这确实是一个shell,那么为什么不处理更长的数据输入流呢

如果缓冲区限制为65/64字节,则编写一个读/处理或解析文本/读/解析等循环


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

您应该真正接受任意大小的行。请注意,读取a(例如在终端中)与读取(例如某些管道)不同。伪tty-s是一个复杂的主题:一些行缓冲发生在内核中

而且你应该有一些缓冲——你通常可以读取比你需要的更多的字节,所以把多余的字节保留在缓冲区中以备将来使用

因此,您应该对缓冲区进行malloc处理,并在缓冲区太小时重新分配它。如果您不允许malloc,请使用mmap实现您自己的分配器


仔细阅读手册页。不要忘记,它可能在出错时返回-1,在文件末尾返回0,或者在成功时返回一些计数。

我认为您不应该限制输入行的大小。使用@BasileStarynkevitch Yea可以,但我只能对IO使用系统调用。然后确保您的缓冲区增长到始终适合内部的一行,可能使用malloc…@BasileStarynkevitch,但这如何解决区分缓冲区溢出和完全缓冲区后按ctrl-D键的问题?@Ataraxia,嗯?写和读也是包装系统调用的stdlib函数。puts&friends不做其他事情。还是只允许编写内联程序集!?这回答了什么是生成shell的一种方法?但是你对如何解决我在问题中提到的问题有什么建议吗?我在问题中说,如何在接收到准确的65个字节并后跟ctrl-D后终止执行?Ataraxia,我们正在讨论程序员和程序员分析师之间的区别。虽然程序员只会做他/她被告知要做的事情,但分析师会检查问题的需求,并找到提供最多功能的最简单解决方案。我认为你的用户不会喜欢输入66个字符的信息。然后被告知重新开始!!是的,我同意字符限制太小。但不幸的是,在这种特殊情况下,设计约束不是由我决定的。所以我不能在这里做程序员分析师……不管有人告诉你什么,这里没有字符限制!除非你没有提到一个关键的事实,这将改变这样的评论。理论上,您可以一次读取一个字符来发出系统调用。这一直是在编译器的解析器中编码的。如果没有其他内容,每次读取一个字符,当字符数=65且未找到ctrl-d时,则惩罚用户。我负责制作的程序中有一个字符限制,我的程序负责执行该限制。好的,我澄清了问题并删除了一些分散注意力的元素,如提到这是用于shell。我感谢你的帮助,但我相信我可能没有把问题说得尽可能清楚。
#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;
}