You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言实现here document如何突破4096字节输入限制?

解决C语言处理超长输入行(超过4096字节)的问题

问题描述

我在C语言中实现类似bash的here document功能时,发现无法处理超过4096字节的输入行。经查这是内核I/O队列的最大尺寸限制导致进程无法接收完整的shell输入,但bash的heredoc却能正常处理该情况,请问是否有办法在C语言中解决此问题?

当输入内容超过4096字符时,程序仅会输出前4096字符或输入出现损坏。测试代码如下:

#include <unistd.h>

int main()
{
    ssize_t r_bytes;
    char buf[42];
    while (r_bytes = read(0, buf, 42))
    {
        write(1, buf, r_bytes);
    }
    return (0);
}

测试步骤

  • 编译并执行上述代码。
  • 输入以下超长内容:
<start>herrslcrwhjsyxlnuvxoofkmnnqnqplyyomfekjdvifzmzqsjjffjlqgvxrmhplzfaywnsptodrwygvhtplduhivfefqefkwcrficiatatbvlpzikietxdfekfnqvgazseylfagktlaseeedbbeajmnvshwkzvlfyhdoswwzzdesnaphprclhihfdckjcpepytllszcucuyvgqlfreyknejkjbthgociqxzellhzgdqkpnglnaocygxqifkjikcrepkcosxclwqlhhgzndoqroocniwrjaoumuvlvtvdrsyaupmkldzhvurnzgwhpvsyzrqzxgtlythlqflciocyepzbxyepegfxifkuopqrivsnhzqhmjmbrdkoxwrgpmdntoqlksjxwrfdadkjzjvyknulhlhmseykfpqnpvfpfbxncefcbfzdfndkwskdusuhylklqcxnmbibgmerllmzgmorqpqawbiexnbgkuaxbiucrkfsxndhdifgrfiuyanximidvvfaqnurmsnvfnwahuvpyjjvpukbrkemqotmvnvqcwivueqisxqvrfunmaaeuguqpullxgyuypepxgkrmgpfxlihmazubjmnlifqoyfidhpvvpyraddjlxoalrhsrpviqkhmcszkluelumfpukwynrmlhdvnwhhukorlpqzouzakphkgorumfqabjxrtghrvynqazsoahewbhpujofcokzeapdlpkgzrrdnmmwintaoowbzctqnxatvfecwnirxaacqmsrbecdgikauqosygzyxkyfikryohidyslrizbwnnhbiwnqbbgqylhvkmtnazfdzvweucoqdovuzfuqlywxdfkmzgsssnprekjfnutlmhbdvtcngeitphqywvtmppptaxyielehppdxjgzuvwybjealhkjjlgibgjcysgvmgfvgqpnpmadtjlngmsxgvolvdlzkfyfqoujjiegunytjkxornyruaxgpqqjhqyfwymvyglnccfbdslqdbrqpmwtonklsajnuaemvkqwjuscectjwbvohfvuecltlkhszplqxipaymbtxjztjofubjblqrrantnfcsoirrvkwnvmwnwqpdsysqsokmwylnvvryhnaatnlbmvtfhbquzmnrukbvqbvwjdqrdgthrqpnjebcokbroruogaswulugwxkrrmbrkskqhlgbufanzafdsbgcqcjxntmczmzrsjqjfcpmetvjirmcpmfmobfslagzlvoppuachoyxbrgqejrdbykeczesigwwcmjdmvvzudouderjbhpihwaxhizaxejmckwnwgmhcgylephrukykldufcobjqrmiiqnxznmlnzpdbxgyxfnwdtgjeupvxdnzyvivpuvrfulypwzfgxmnomohfcvcyuhimpeelkwaurwcgcthvsfpppurrercewdfhryyyytzowizhtlzohewpqxjmacpgkhvjzopuoggswmowcbfhkdpkvbjajqjmqfqbovgiaojsfyaqzqmngemgytcsvsqfdpbcehxrcleqmguhnuipoqecwralfehnxrevtmgqbiqpfighujwpgqqfcumppeamwasfqkeochbptmezrmttngijtwawvojpmpkzozkkxzuxzggvcswowkjmtvtmzwptwolaflkddwbkmzxvnclqzsikajmyihcatjrnvqixbfnmpvigmmwmepppebohsidrquffvkmjxtuchozqbdcowfqpnrhxzrkxozpqfojuybxwcerlfmaveslyfnkvkphotyrdukcelzszlqaqyayvuzljfsgrltqherbwabxslbwxlrfnundvzvchgpllcenakkwaejdejpfqiarsomxgcoplpdrqdudcaopdxjziyvuqeolkqqopwzixmhpyaabjuoplqourpuzphjfyvvwoxlssgkkqrwewzikvkdgfwgtzkennzhlnuakywfiiwqvpsfqgkowunzfblrxiwqibulojvrjnbhgjookrazjzrhmhqxnxjmaupdczcwlhmhvaepgvdksckettpzqhkfbmszbqbqidnjnwcrloqduucjdgvisrlixrwsqtdrackbbwbfslpgrkycycqnbccebvcuivfkyejwwcfpuaqmuacfrcbjtmvwvcryuzlbvuwagcggiwwzxxbicvnwbafuubeqjuvrdcizwbnagdntjypfolexpesovyrupoxlnhtdcnhyppxoniqdpsfyhlarshtdgwbtbkjtklvdpztdumykphalytjaefwfhwhhnpqcwfcruhmmxoqngnvtfbxwfmfdkhivhitsdecqehowjmgxmdipdtsiwuxivdjmmwrkotqrdhwtnzfbhemboqkqkodaabxkedzkpxriuurifgfjhrtxpqlaoolqgbkdqyaatgnsdzhawpfhvwgtqjsdeopuwvgolouofwwzbhpeybvpglwwqjcjlqpsobgojoijblingffcrsydqcjjzlwoeklhxzecitrtihakcktvfnfblmhejybnsihzhmcgxayxoruyvnecnbbfpwieoejtfzjhjczduuldcflvwzjzruxlckvpyivtnyzfzdhfzptwjjggaeqsbgkkynqjpsuobflnaqbwayslrsvrgrbtjzhkbtmvicoxbdfexnuwzbvamumswnloymrjojujwtmcudbhcxvbxbcwzrzhjlrgoerptgczhldyskvqpqxxpuywrtltwyzkbpdmzgcaulbdygqfeoflgwnhtuaelesgjaawskmsccgyoqraabxppuueyfbdvuhvotgbswrtyfxliwkewxzpoetubihymgbmqnmaseemmonsgkbfsomawfjgxqqrjbfxpyissubkeafseucdpwasafhkkhsdygbgeypjesxeyafbdctkgorlcknmjtnqpjbkwwyztqailtefgjmkgujpynkfmtqnjvdqjgttnvejsvzahddzedysitrwumidnufktcozdfgshwzicuykokdjxszhcsimalzijyvylkaxdweafmtfgtkaepteyafqijbonhgxrqnkxwtpceajseopimpkvouzajzrrtbpiymsqxnrkmpejokpancnmmcincaddywnozsknikimutldarwabrzgvymatbamsbwaikbwatvqbpvfsdeafycximswbehmyzwzarqvcjtzyofhfjxagtrehvssqsbtowueuizqjuyjrulldgxtjtkirekhwaxhdfcnbwhyqtuinxpxddkvoiveoenwsgixpqqxupuunrgyddowemsegsovkigdwxgefzvmiuuafynnxukixpsnmiwszojlmcxvopwdazpcuxetclgatgzmvmeecppggaqhobatlyynzhdygxiatrktpgntmkqcjkuxmdlroounnxcebepchuokotvmqfctmtjsnplgjmeobzbwhxekvlbknvwughuppzuecumvqjylqkhlmpbbhmgrenotwyyquqhgrrboqvjskaczyhnukqogmqbngkrvsakcppveykzuqmsbxdfxjulofmpnilynqzzgdxbdjjzhskrthbwzjzugjsutgpgkromaccbjqitrhxlahzaygcvztjycifokrbxugvdmwxqqxibhgckxwhabbjsmnpencsplrxjnfanqtdgrruiomesapwfdvsotvkgqgfxeelavujnigyedrhwksraopenosfgbrdvogtudmxecvrvxvjjuaodjvajlgazeqsyemyysxpnilklpvzciwidtjebaczuhezsresvglzivbbodxakeighfawfanvdzzpadrcisfsqyhfbuyurppqdfekrolbzxvquulxhnwwndndirrcysbywooygizgbuiezholvuoqkyiorttcmzpseippnxkuilfsrxfknzkvzlqmdlupqkxdjxtiuxjghikocnpkocoauecaofnsyouizpbgvytkpxrfalhvpqymbxqetmozufwmcbycsalporhqzlfpbeqgffteuqeatujlrjyjhjjjhj<end>helloworld

程序输出内容仅到<end>或出现4096字符的损坏字符串。

解决方案

1. 修改终端为非规范模式

shell终端默认的规范模式会限制输入行长度(通常对应MAX_INPUT宏的4096字节),bash会主动调整这个限制,而普通C程序会继承终端的默认设置。可以在程序中通过终端属性函数修改为非规范模式,关闭行缓冲:

#include <unistd.h>
#include <termios.h>
#include <stdlib.h>

int main() {
    struct termios old_termios, new_termios;
    ssize_t r_bytes;
    char buf[42];

    // 保存原有终端属性
    if (tcgetattr(STDIN_FILENO, &old_termios) == -1) {
        return 1;
    }
    // 设置非规范模式,关闭行缓冲与回显
    new_termios = old_termios;
    new_termios.c_lflag &= ~(ICANON | ECHO);
    new_termios.c_cc[VMIN] = 1;  // 至少读取1个字符
    new_termios.c_cc[VTIME] = 0; // 无超时等待
    if (tcsetattr(STDIN_FILENO, TCSANOW, &new_termios) == -1) {
        return 1;
    }

    // 循环读取并输出输入内容
    while ((r_bytes = read(STDIN_FILENO, buf, sizeof(buf))) > 0) {
        write(STDOUT_FILENO, buf, r_bytes);
    }

    // 恢复原有终端属性
    tcsetattr(STDIN_FILENO, TCSANOW, &old_termios);
    return 0;
}

2. 通过管道或文件重定向输入

如果不需要交互式输入,直接通过管道或文件重定向提供超长内容,此时终端的行长度限制不会生效,内核会将完整数据传递给程序:

# 从文件读取输入
./your_program < long_input.txt
# 通过管道传递输入
cat long_input.txt | ./your_program

3. 使用标准I/O库替代直接系统调用

标准I/O库(<stdio.h>)会在用户空间维护缓冲区,自动拼接内核分段返回的数据,无需关心内核的单次传输限制:

#include <stdio.h>

int main() {
    char buf[42];
    size_t bytes_read;
    while ((bytes_read = fread(buf, 1, sizeof(buf), stdin)) > 0) {
        fwrite(buf, 1, bytes_read, stdout);
    }
    return 0;
}

内容的提问来源于stack exchange,提问作者Anass Abidar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 15:55:53