我正在try 实现一个像bash(C)中使用的文档一样的here文档,但我注意到我不能为它提供一行长度超过4096字节,我查了查,这是因为内核I/O队列的最大大小,所以我的进程永远不会收到我在shell中输入的完整输入.与此同时,狂欢节的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);
}

1-编译并执行此代码. 2-给它这个输入:

<start>herrslcrwhjsyxlnuvxoofkmnnqnqplyyomfekjdvifzmzqsjjffjlqgvxrmhplzfaywnsptodrwygvhtplduhivfefqefkwcrficiatatbvlpzikietxdfekfnqvgazseylfagktlaseeedbbeajmnvshwkzvlfyhdoswwzzdesnaphprclhihfdckjcpepytllszcucuyvgqlfreyknejkjbthgociqxzellhzgdqkpnglnaocygxqifkjikcrepkcosxclwqlhhgzndoqroocniwrjaoumuvlvtvdrsyaupmkldzhvurnzgwhpvsyzrqzxgtlythlqflciocyepzbxyepegfxifkuopqrivsnhzqhmjmbrdkoxwrgpmdntoqlksjxwrfdadkjzjvyknulhlhmseykfpqnpvfpfbxncefcbfzdfndkwskdusuhylklqcxnmbibgmerllmzgmorqpqawbiexnbgkuaxbiucrkfsxndhdifgrfiuyanximidvvfaqnurmsnvfnwahuvpyjjvpukbrkemqotmvnvqcwivueqisxqvrfunmaaeuguqpullxgyuypepxgkrmgpfxlihmazubjmnlifqoyfidhpvvpyraddjlxoalrhsrpviqkhmcszkluelumfpukwynrmlhdvnwhhukorlpqzouzakphkgorumfqabjxrtghrvynqazsoahewbhpujofcokzeapdlpkgzrrdnmmwintaoowbzctqnxatvfecwnirxaacqmsrbecdgikauqosygzyxkyfikryohidyslrizbwnnhbiwnqbbgqylhvkmtnazfdzvweucoqdovuzfuqlywxdfkmzgsssnprekjfnutlmhbdvtcngeitphqywvtmppptaxyielehppdxjgzuvwybjealhkjjlgibgjcysgvmgfvgqpnpmadtjlngmsxgvolvdlzkfyfqoujjiegunytjkxornyruaxgpqqjhqyfwymvyglnccfbdslqdbrqpmwtonklsajnuaemvkqwjuscectjwbvohfvuecltlkhszplqxipaymbtxjztjofubjblqrrantnfcsoirrvkwnvmwnwqpdsysqsokmwylnvvryhnaatnlbmvtfhbquzmnrukbvqbvwjdqrdgthrqpnjebcokbroruogaswulugwxkrrmbrkskqhlgbufanzafdsbgcqcjxntmczmzrsjqjfcpmetvjirmcpmfmobfslagzlvoppuachoyxbrgqejrdbykeczesigwwcmjdmvvzudouderjbhpihwaxhizaxejmckwnwgmhcgylephrukykldufcobjqrmiiqnxznmlnzpdbxgyxfnwdtgjeupvxdnzyvivpuvrfulypwzfgxmnomohfcvcyuhimpeelkwaurwcgcthvsfpppurrercewdfhryyyytzowizhtlzohewpqxjmacpgkhvjzopuoggswmowcbfhkdpkvbjajqjmqfqbovgiaojsfyaqzqmngemgytcsvsqfdpbcehxrcleqmguhnuipoqecwralfehnxrevtmgqbiqpfighujwpgqqfcumppeamwasfqkeochbptmezrmttngijtwawvojpmpkzozkkxzuxzggvcswowkjmtvtmzwptwolaflkddwbkmzxvnclqzsikajmyihcatjrnvqixbfnmpvigmmwmepppebohsidrquffvkmjxtuchozqbdcowfqpnrhxzrkxozpqfojuybxwcerlfmaveslyfnkvkphotyrdukcelzszlqaqyayvuzljfsgrltqherbwabxslbwxlrfnundvzvchgpllcenakkwaejdejpfqiarsomxgcoplpdrqdudcaopdxjziyvuqeolkqqopwzixmhpyaabjuoplqourpuzphjfyvvwoxlssgkkqrwewzikvkdgfwgtzkennzhlnuakywfiiwqvpsfqgkowunzfblrxiwqibulojvrjnbhgjookrazjzrhmhqxnxjmaupdczcwlhmhvaepgvdksckettpzqhkfbmszbqbqidnjnwcrloqduucjdgvisrlixrwsqtdrackbbwbfslpgrkycycqnbccebvcuivfkyejwwcfpuaqmuacfrcbjtmvwvcryuzlbvuwagcggiwwzxxbicvnwbafuubeqjuvrdcizwbnagdntjypfolexpesovyrupoxlnhtdcnhyppxoniqdpsfyhlarshtdgwbtbkjtklvdpztdumykphalytjaefwfhwhhnpqcwfcruhmmxoqngnvtfbxwfmfdkhivhitsdecqehowjmgxmdipdtsiwuxivdjmmwrkotqrdhwtnzfbhemboqkqkodaabxkedzkpxriuurifgfjhrtxpqlaoolqgbkdqyaatgnsdzhawpfhvwgtqjsdeopuwvgolouofwwzbhpeybvpglwwqjcjlqpsobgojoijblingffcrsydqcjjzlwoeklhxzecitrtihakcktvfnfblmhejybnsihzhmcgxayxoruyvnecnbbfpwieoejtfzjhjczduuldcflvwzjzruxlckvpyivtnyzfzdhfzptwjjggaeqsbgkkynqjpsuobflnaqbwayslrsvrgrbtjzhkbtmvicoxbdfexnuwzbvamumswnloymrjojujwtmcudbhcxvbxbcwzrzhjlrgoerptgczhldyskvqpqxxpuywrtltwyzkbpdmzgcaulbdygqfeoflgwnhtuaelesgjaawskmsccgyoqraabxppuueyfbdvuhvotgbswrtyfxliwkewxzpoetubihymgbmqnmaseemmonsgkbfsomawfjgxqqrjbfxpyissubkeafseucdpwasafhkkhsdygbgeypjesxeyafbdctkgorlcknmjtnqpjbkwwyztqailtefgjmkgujpynkfmtqnjvdqjgttnvejsvzahddzedysitrwumidnufktcozdfgshwzicuykokdjxszhcsimalzijyvylkaxdweafmtfgtkaepteyafqijbonhgxrqnkxwtpceajseopimpkvouzajzrrtbpiymsqxnrkmpejokpancnmmcincaddywnozsknikimutldarwabrzgvymatbamsbwaikbwatvqbpvfsdeafycximswbehmyzwzarqvcjtzyofhfjxagtrehvssqsbtowueuizqjuyjrulldgxtjtkirekhwaxhdfcnbwhyqtuinxpxddkvoiveoenwsgixpqqxupuunrgyddowemsegsovkigdwxgefzvmiuuafynnxukixpsnmiwszojlmcxvopwdazpcuxetclgatgzmvmeecppggaqhobatlyynzhdygxiatrktpgntmkqcjkuxmdlroounnxcebepchuokotvmqfctmtjsnplgjmeobzbwhxekvlbknvwughuppzuecumvqjylqkhlmpbbhmgrenotwyyquqhgrrboqvjskaczyhnukqogmqbngkrvsakcppveykzuqmsbxdfxjulofmpnilynqzzgdxbdjjzhskrthbwzjzugjsutgpgkromaccbjqitrhxlahzaygcvztjycifokrbxugvdmwxqqxibhgckxwhabbjsmnpencsplrxjnfanqtdgrruiomesapwfdvsotvkgqgfxeelavujnigyedrhwksraopenosfgbrdvogtudmxecvrvxvjjuaodjvajlgazeqsyemyysxpnilklpvzciwidtjebaczuhezsresvglzivbbodxakeighfawfanvdzzpadrcisfsqyhfbuyurppqdfekrolbzxvquulxhnwwndndirrcysbywooygizgbuiezholvuoqkyiorttcmzpseippnxkuilfsrxfknzkvzlqmdlupqkxdjxtiuxjghikocnpkocoauecaofnsyouizpbgvytkpxrfalhvpqymbxqetmozufwmcbycsalporhqzlfpbeqgffteuqeatujlrjyjhjjjhj<end>helloworld

输出是直到结束或损坏的4096字符串为止的所有内容.

推荐答案

要处理C中超过4096个字节的输入行,您可以将终端切换到Non-Canonical mode(也称为Raw mode).

在非规范模式下,输入即可立即可用,无需等待白线,从而允许您处理超过典型缓冲区大小的输入.

查看您的代码,如上所述进行了修改:

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

void setRawMode(int fd) {
    struct termios term;

    tcgetattr(fd, &term);
    term.c_lflag &= ~(ICANON | ECHO);
    tcsetattr(fd, TCSANOW, &term);
}

void setCanonicalMode(int fd) {
    struct termios term;

    tcgetattr(fd, &term);
    term.c_lflag |= (ICANON | ECHO);
    tcsetattr(fd, TCSANOW, &term);
}

int main() {
    setRawMode(STDIN_FILENO);

    ssize_t r_bytes;
    char    buf[64];

    while ((r_bytes = read(STDIN_FILENO, buf, sizeof(buf) - 1)) > 0) {
        buf[r_bytes] = '\0'; 
        printf("%s", buf);
    }

    setCanonicalMode(STDIN_FILENO);

    return 0;
}

C++相关问答推荐

如何将不同长度的位转换成字节数组?

在C语言中使用scanf()时我无法理解的警告

在使用GTK 4 Columnview列表模型时,如何为多列添加排序函数.C编码,Linux/GNOME环境

我无法让LLDB正确运行我的可执行文件

模拟shell并运行.sh文件

正确的TCP/IP数据包 struct

如何使用指向 struct 数组的指针并访问数组中特定索引处的 struct

S的这种管道实施有什么问题吗?

为什么函数是按照定义的顺序执行的,而不是按照从avr-c中的int main()调用的顺序执行的?

为 struct 中的数组动态分配内存时出错

C语言中MPI发送接收字符串时出现的分段错误

如果格式字符串的内存与printf的一个参数共享,会发生什么情况?

OSDev--双缓冲重启系统

对于STM32微控制器,全局偏移表.get和.Got.plt必须为零初始化

生成一个半RNG,结果用C表示(无随机/随机)

是否有单独的缓冲区用于读写库调用?

为什么我在我的代码中得到错误和退出代码-1073741819(0xC0000005),但如果我添加了一个不相关的打印语句,它仍然有效?

关于不同C编译器中的__attribute__支持

OpenGL 中的非渐变 colored颜色 变化

如何确保 gcc + libc 对于多字节字符串使用 UTF-8,对于 wchar_t 使用 UTF-32?