【问题标题】:How can i properly read an input from stdin with a buffer without truncating any words?如何在不截断任何单词的情况下使用缓冲区从标准输入正确读取输入?
【发布时间】:2015-04-23 10:52:57
【问题描述】:

您好,我正在编写一个简单的程序,该程序打算从标准输入读取一些文本,然后在该文本中找到一些单词并将其替换为“?”字符,最后将结果放到标准输出中。

我的问题是,如果当前缓冲区在一个单词的中间结束并且我正在搜索该单词,“strstr”函数不会将它作为命中。

示例:

Buffer 为 10 并找到单词“amazing”

输入:“Wordnet 是一款真正令人惊叹的软件,我们在 Roistr 经常使用它来实现语义相关性。其中一个有用的部分是每个同义词集都有使用中的词义示例。但有时,这些可能会误导一点”

第一个缓冲区:“Wordnet 是”-> 没有命中

第二个缓冲区:“一个真正的 a”-> 没有命中

第三个缓冲区:“mazing pie” -> 没有命中

正如您在第三个缓冲区中看到的那样,我对惊人这个词得到了误报,因为它被缓冲区长度截断了。

我需要一个不依赖于缓冲区大小的解决方案,因为例如缓冲区 [500] 将解决此示例中的问题,但如果我输入 50000,则问题可能会再次出现。

谢谢

对不起我的英语。

我的代码:

    char* aux = "is";
    char* pch;
    char buff[100];
    int readd;


    int stringsize = strlen(aux);


    while (((readd = read(0, buff, sizeof buff)) > 0)) {

        pch = strstr(buff, aux);

        if (pch != 0) {
            strncpy(pch, "?????????????????", stringsize);
        }

        write(1, buff, readd);
    }

其他详情:

语言:C

环境:Linux/POSIX

【问题讨论】:

  • 使缓冲区动态化,一次读取一个字符,直到你得到一个换行符,追加到缓冲区,满时重新分配缓冲区。或者使用getline,这将确保你得到一整行,并为你分配内存。
  • @holyknight。如果文件包含行,您可以使用 fgets() 一次加载一行(如果您使用的缓冲区可能包含文件中较大的行)。但是,您必须注意连字符。另一种方法可能是获取所有后跟空格(或 \t \n \r)的单词。所以在缓冲区的末尾只剩下一个词或一个词。然后复制缓冲区顶部的剩余字节并从文件中加载新行(注意缓冲区包含一些数据)。

标签: c linux buffer posix stdin


【解决方案1】:

有多种方法可以解决此问题。

其中一个(可能最接近您的解决方案)是逐个字符读取输入并检测每个单词的开头和结尾(使用空格作为分隔符)。当您到达一个单词的结尾时,您将它与您正在搜索的单词进行比较,然后您就完成了。

可以使用格式化输入(类似于 scanf)来简化上述内容,这样您就可以读取到第一个空格。

更复杂的方法是像现在一样读取,如果当前缓冲区中的最后一个单词没有完成(例如,您可以通过验证缓冲区是否以空格结尾来检查这一点),把最后一部分缓冲区(从最后一个空格开始到结尾的部分)回到标准输入(使用类似 ungetch() 的东西)。当你再次读取缓冲区时,你会得到完整的单词。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-07-18
    • 2014-10-02
    • 2011-05-18
    • 1970-01-01
    • 1970-01-01
    • 2011-01-23
    • 2020-08-06
    • 1970-01-01
    相关资源
    最近更新 更多