fgets提示限制为1024字节 [英] fgets prompt limited to 1024 Bytes

查看:249
本文介绍了fgets提示限制为1024字节的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在努力解决一个非常简单的问题,该问题用 C 编写了一个小程序.

只要输入的大小不超过1024字节,就可以通过fgets()获取输入(命令,参数,要执行的标志).键入1024个字符后,不再接受任何字符-提示停止.我认为问题的原因不在fgets()参数/配置中,因为否则它将至少使输入达到定义的大小,而不是阻塞.

我如何使fgets()接受只要_SC_LINE_MAX(2048)个字节/字符的行?

解决方案

终端驱动程序限制输入线的长度

正如我在评论中指出的那样,问题几乎可以肯定是您的终端驱动程序不允许您输入长度超过1024字节的行.它不会分配更多的存储空间.这适用于规范"模式;有关更多信息,请参见规范与非规范终端输入.那个.

有一个简单的测试程序(现在在问题中).在Mac OS X 10.11.4上运行它时,我可以输入1023个字符加上换行符,或者输入1024个字符,但不能输入换行符,直到删除一个为止.

为记录起见,输入字符串为:

12345678901234567890123456789X123456789Y123456789Z123456789A123456789B123456789C123456789D123456789e123456789f123456789g123456789h123456789i123456789j123456789k123456789l123456789m123456789n123456789o123456789p123456789q123456789r123456789s123456789t123456789s123456789t123456789u123456789v123456789w123456789x123456789y123456789z123456789a123456789b123456789c123456789d123456789e123456789f123456789g123456789h123456789i123456789j123456789k123456789l123456789m123456789n123456789o123456789p123456789q123456789r123456789s123456789t123456789u123456789v123456789w123456789x123456789y123456789z123456789a123456789b123456789c123456789d123456789e123456789f123456789g123456789h123456789i123456789j123456789k123456789l123456789m123456789n123456789o123456789p123456789q123456789r123456789s123456789t123456789u123456789v123456789w123456789x123456789y123456789z123456789a123456789b123456789c123456789d123456789e123456789f123456789g123456789h123456789i123456789j123456789k123456789l123456789m123456789n123456789o123456789p123456789q123

如果使用换行符复制并粘贴该行,则可能会输入OK.如果再添加其他字符,则可能会收到终端提示音.

还有另一个问题( fgets()限制为1024个字节-我可以使用什么代替?)几乎可以肯定会遇到相同的问题-并且实际上没有得到太多有用的帮助.

如果您使用GNU之类的库 readline 库,它可以将终端置于非规范模式,然后可以处理更长的行,因为终端驱动程序在将数据发送到程序之前不会等到输入换行符.在类似Linux的系统上,重建具有更大终端输入线长度限制的内核在名义上是一个选项,但对于临时程序员而言并不是一项任务.

LINE_MAX和相关宏的含义

还要注意,_SC_LINE_MAX sysconf() 代码确定LINE_MAX的方法,该值必须至少为{POSIX2_LINE_MAX}的值(最小2048),该文档记录为:

除非另有说明,否则当实用程序被描述为处理文本文件时,该实用程序(标准输入或另一个文件)的输入行的最大长度(以字节为单位).长度包括尾随<newline>的空间.

请注意,终端不是文本文件.此限制表明,grep之类的实用程序一定不能对2048字节长的行进行错误处理,但是它可能会被更长的行弄糊涂(例如,因为它读取一行2048字节的数据块,并且开始行"在长行的第二个或后续大块的开头匹配).

POSIX注释的原理:

{LINE_MAX}

除非另有说明,否则这是一个影响所有实用程序的全局限制. POSIX.1-2008的系统接口卷中的{MAX_CANON}值可能会进一步限制来自终端的输入线. {LINE_MAX}的值是很多争论的主题,它是那些希望有无限行的人和那些理解许多历史实用程序是用固定缓冲区编写的人之间的折衷方案.实用程序作者经常选择UNIX系统常量BUFSIZ来分配这些缓冲区.因此,某些实用程序的I/O线路限制为512字节,而其他实用程序达到4096字节或更大.

应注意,{LINE_MAX}仅适用于输入线长; POSIX.1-2008中没有限制输出线长度的要求.理论上,诸如awksedpaste的实用程序可以构造的线长于它们接收到的任何输入线,这取决于所使用的选项或应用程序中的指令.他们不需要将其输出截断为{LINE_MAX}.处理此事是应用程序的责任.如果要将其中一个实用程序的输出通过管道传输到另一个标准实用程序中,则必须考虑行长限制. fold实用程序可用于确保只有合理的行长才能到达实用程序或应用程序.

引用的{MAX_CANON}描述为:

{MAX_CANON}

终端规范输入行中的最大字节数.
最小可接受值:{_POSIX_MAX_CANON}

在其他地方(<limits.h>),_POSIX_MAX_CANON的最小可接受值为255.

I have been struggling with a pretty simple issue writing a little program in C.

Getting input (commands, arguments, flags to be executed) via fgets() works fine as long as the size of the input does not exceed 1024 bytes. After 1024 characters are typed, no more characters are accepted -- the prompt just stops. I assume reason for the problem doesn't lay in the fgets() parameters/configuration because otherwise it would at least take the input up to defined size instead of blocking.

How can I make fgets() accept lines as long as _SC_LINE_MAX (2048) bytes/chars?

解决方案

Terminal drivers limit the length of input lines

As I noted in the comments, the trouble is almost certainly that your terminal driver won't allow you to enter lines that are longer than 1024 bytes; it won't allocate more storage. That applies in 'canonical' mode; see Canonical vs non-canonical terminal input for more information about that.

There's a simple test program (now in the question). When I run it on Mac OS X 10.11.4, I can enter 1023 characters plus newline, or 1024 characters but no newline until I delete one.

For the record, the input string was:

12345678901234567890123456789X123456789Y123456789Z123456789A123456789B123456789C123456789D123456789e123456789f123456789g123456789h123456789i123456789j123456789k123456789l123456789m123456789n123456789o123456789p123456789q123456789r123456789s123456789t123456789s123456789t123456789u123456789v123456789w123456789x123456789y123456789z123456789a123456789b123456789c123456789d123456789e123456789f123456789g123456789h123456789i123456789j123456789k123456789l123456789m123456789n123456789o123456789p123456789q123456789r123456789s123456789t123456789u123456789v123456789w123456789x123456789y123456789z123456789a123456789b123456789c123456789d123456789e123456789f123456789g123456789h123456789i123456789j123456789k123456789l123456789m123456789n123456789o123456789p123456789q123456789r123456789s123456789t123456789u123456789v123456789w123456789x123456789y123456789z123456789a123456789b123456789c123456789d123456789e123456789f123456789g123456789h123456789i123456789j123456789k123456789l123456789m123456789n123456789o123456789p123456789q123

If you copy and paste that with the newline, it will probably be entered OK. If you add any more characters, you will probably get the terminal beeping at you.

There's another question (fgets() is limited to 1024 bytes — what can I use instead?) that almost certainly ran into the same problem — and really wasn't given much in the way of useful help.

If you use a library such as the GNU readline library, it can put the terminal into non-canonical mode and then can handle longer lines because the terminal driver doesn't wait until the newline is entered before sending the data to the program. Rebuilding the kernel with a bigger limit on the terminal input line length is nominally an option on Linux-like systems, but not a task for the casual programmer.

Meaning of LINE_MAX and related macros

Also note that _SC_LINE_MAX is the sysconf() code for determining LINE_MAX, which must be at least the value of {POSIX2_LINE_MAX} (minimum 2048), which is documented as being:

Unless otherwise noted, the maximum length, in bytes, of the input line of a utility (either standard input or another file), when the utility is described as processing text files. The length includes room for the trailing <newline>.

Note that a terminal is not a text file. This limit says that utilities such as grep must not mishandle lines that are 2048 bytes long, but it might get confused by longer lines (for example, because it reads 2048-byte chunks of a line, and does 'beginning of line' matches at the start of the second or subsequent chunks of a long line).

The rationale for POSIX notes:

{LINE_MAX}

This is a global limit that affects all utilities, unless otherwise noted. The {MAX_CANON} value from the System Interfaces volume of POSIX.1-2008 may further limit input lines from terminals. The {LINE_MAX} value was the subject of much debate and is a compromise between those who wished to have unlimited lines and those who understood that many historical utilities were written with fixed buffers. Frequently, utility writers selected the UNIX system constant BUFSIZ to allocate these buffers; therefore, some utilities were limited to 512 bytes for I/O lines, while others achieved 4096 bytes or greater.

It should be noted that {LINE_MAX} applies only to input line length; there is no requirement in POSIX.1-2008 that limits the length of output lines. Utilities such as awk, sed, and paste could theoretically construct lines longer than any of the input lines they received, depending on the options used or the instructions from the application. They are not required to truncate their output to {LINE_MAX}. It is the responsibility of the application to deal with this. If the output of one of those utilities is to be piped into another of the standard utilities, line length restrictions will have to be considered; the fold utility, among others, could be used to ensure that only reasonable line lengths reach utilities or applications.

And the {MAX_CANON} referenced is described as:

{MAX_CANON}

Maximum number of bytes in a terminal canonical input line.
Minimum Acceptable Value: {_POSIX_MAX_CANON}

And elsewhere (<limits.h>), the minimum acceptable value for _POSIX_MAX_CANON is 255.

这篇关于fgets提示限制为1024字节的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆