如何在接受stdin输入的同时使C程序连续执行?

硬件135

以下是myprogram.c的摘录:

int main(int argc, char *argv[])
{
   UserOptions opt;
   DmtxEncode *enc;
   unsigned char codeBuffer[BUFFER_SIZE];
   int codeBufferSize;
   opt = GetDefaultOptions();


   /* Read input data into buffer */
   codeBufferSize = ReadInputData(codeBuffer, &opt);

   //do something with the input data

   exit(0);
}

static size_t ReadInputData(unsigned char *codeBuffer, UserOptions *opt)
{
   int fd;
   ssize_t bytesRead;
   size_t bytesReadTotal;

   /* Open file or stdin for reading */
   fd = (opt->inputPath == NULL) ? 0 : open(opt->inputPath, O_RDONLY);

   /* Read input contents into buffer */
   for(bytesReadTotal = 0;; bytesReadTotal += bytesRead) {
      bytesRead = read(fd, codeBuffer + bytesReadTotal, BUFFER_SIZE);
      if(bytesRead == 0)
         break;
   }

   return bytesReadTotal;
}

这将采用形式的输入,echo 1234 | myprogram并且程序将生成输出并终止。

我想使该程序连续执行并接受用户输入,其中两个单独的输入以换行符(\n区分例如说我想1234 \n 5678 \n 6363 \n作为输入。程序应首先获取输入1234,为其生成输出,然后查看是否存在换行符,并将其5678视为第二输入,生成输出,依此类推。

我尝试过ReadInputData如下修改功能:

static size_t ReadInputData(unsigned char *codeBuffer, UserOptions *opt) {
    int fd;
    ssize_t bytesRead;
    size_t bytesReadTotal;
    size_t startOfBlock;
    unsigned char tmpBuffer[BUFFER_SIZE];

    /* Open file or stdin for reading */
    fd = (opt->inputPath == NULL) ? 0 : open(opt->inputPath, O_RDONLY);

    for (bytesReadTotal = 0;; bytesReadTotal += bytesRead) {

        startOfBlock = tmpBuffer + bytesReadTotal;
        bytesRead = read(fd, startOfBlock, BUFFER_SIZE);

        for (int i = startOfBlock; i < startOfBlock + bytesRead; i++) {
            if (tmpBuffer[i] != '\n')
                codeBuffer[i] = tmpBuffer[i];
            else
                break;
    }
    }


    return bytesReadTotal;
}

并将其工作封装main在一个while(1)循环中,但这只会产生单个输入的输出并终止程序。

有人可以帮我弄清楚我在做什么错吗?

编辑:根据建议,我修改了ReadInputData如下功能:

static size_t
ReadInputData(unsigned char *codeBuffer, UserOptions *opt) {
    int fd;
    ssize_t bytesRead;
    size_t bytesReadTotal;
    unsigned char* startOfBlock;
    unsigned char tmpBuffer[BUFFER_SIZE];

    /* Open file or stdin for reading */
    fd = (opt->inputPath == NULL) ? 0 : open(opt->inputPath, O_RDONLY);

    for (bytesReadTotal = 0;; bytesReadTotal += bytesRead) {

        startOfBlock = tmpBuffer + bytesReadTotal;
        bytesRead = read(fd, startOfBlock, DMTXWRITE_BUFFER_SIZE);

        if (bytesRead == 0)
            break;
        if (bytesRead == -1)
            FatalError(EX_IOERR, _("Message read error"));
        else if (bytesReadTotal > DMTXWRITE_BUFFER_SIZE)
            FatalError(EX_DATAERR, _("Message to be encoded is too large"));

        for (int i = 0; i < bytesRead; i++) {
            if (startOfBlock[i] != '\n')
                codeBuffer[i] = startOfBlock[i];
            else
                break;
        }

    }

这解决了换行符的问题,但是程序在接受一个输入而不是接受连续输入后退出。的内容mainwhile(1)循环内。

编辑:main带有while循环。exit(0)存在main

int main(int argc, char *argv[])
{
   UserOptions opt;
   DmtxEncode *enc;
   unsigned char codeBuffer[BUFFER_SIZE];
   int codeBufferSize;
   opt = GetDefaultOptions();

   while(1){

   /* Read input data into buffer */
   codeBufferSize = ReadInputData(codeBuffer, &opt);

   //do something with the input data

   }

}
杰里米

中的代码存在很多问题ReadInputData最大的问题是两次调用之间不会保留您的输入。read将获得所有可用数据(取决于您传递的数量)。因此,如果碰巧有两行可用,ReadInputData将它们都放入tmpBuffer保存第一个,tmpBuffer超出范围第二个丢弃

您需要在调用之间保留的缓冲区。

另一个问题是此测试:

else if (bytesReadTotal > DMTXWRITE_BUFFER_SIZE)

如果DMTXWRITE_BUFFER_SIZE非常小,使得前两行加在一起大于此数量,则会出现致命错误。我敢肯定,您确实需要这样的东西:

if (bytesReadTotal == BUFFER_SIZE)
{
    FatalError(EX_DATAERR, _("Message to be encoded is too large"));
}
bytesRead = read(fd, startOfBlock, min(DMTXWRITE_BUFFER_SIZE BUFFER_SIZE, BUFFER_SIZE - bytesReadTotal));

也就是说,在读取之前,您需要确保缓冲区中有空间另外,阅读没有意义,没有超出您的允许范围。


回到第一个问题,有两种方法可以解决此问题。

  1. 品牌tmpBufferbytesReadTotal静态变量

  2. 将它们放在a中struct,并将指向它的指针传递给通话

struct ReadBuffer
{
    char tmpBuffer[BUFFER_SIZE];
    size_t bytesReadTotal;
}

int main(int argc, char *argv[])
{
    struct ReadBuffer buffer;
    buffer.bytesReadTotal = 0;

    // stuff 

    codeBufferSize = ReadInputData(codeBuffer, &opt, &buffer);

    // stuff

}

static size_t ReadInputData(unsigned char *codeBuffer, UserOptions *opt, struct ReadBuffer *buffer)
{
    // stuff

    startOfBlock = buffer.tmpBuffer + buffer.bytesReadTotal;
    // and so on
}

然后,您需要添加所有代码来管理缓冲区,依此类推,但是C库中已经存在这种东西,称为a FILE如果您使用标准库缓冲的FILEAPI而不是原始的Unix系统调用,那么您的生活会容易得多。甚至还有一个功能(很多注释都在告诉您使用该功能,该功能读取并返回下一个输入\n。这称为fgets()


刚刚发现了另一个问题。每次调用时都打开文件ReadInputData这不是问题,stdin因为您只使用了文件描述符0。但是,对于任何其他文件,您每次都会读取第一行,直到您的进程用完文件描述符为止。在上面的解决方案中,您必须打开文件,main然后将文件描述符添加到ReadBufferstruct中。如果这样做,则肯定是在重新发明C库FILE

这是一个粗略的重新实现

int main(int argc, char *argv[])
{
   UserOptions opt;
   DmtxEncode *enc;
   unsigned char codeBuffer[BUFFER_SIZE];
   ssize_t codeBufferSize;
   opt = GetDefaultOptions();

   FILE* input = opt->inputPath == NULL ? stdin : open(opt->inputPath, "r");
   if (input == NULL)
   {
       // Handle the error
   } 

   while(1)
   {

       /* Read input data into buffer */
       codeBufferSize = fgets(codeBuffer, BUFFER_SIZE, input);
       if (codeBufferSize == -1)
       {
           // Handfle IO error
       }
       else if (codeBufferSize == 0) 
       { 
           // reached end of file
       }
       else if (codeBuffer[codeBufferSize - 1] != '\n')
       {
           // Handle input truncated because line was too long
       }
       else 
       { 
           //do something with the input dat
       }
   }
   if (input != NULL)  
   {
       fclose(input);
   }
}


本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

我正在尝试创建一个ac程序,它将连续从stdin接受输入,直到输入exit

来自分类Dev

在C中接受用户的连续输入

来自分类Dev

如何在程序开始时接受输入?

来自分类Dev

如何在侦听C语言中的用户输入的同时运行程序?

来自分类Dev

执行程序接受线程作为输入

来自分类Dev

如何在C系统/ popen命令中由另一个C ++程序连续输入?

来自分类Dev

如何在拒绝浮点数和空格的同时接受整数输入?

来自分类Dev

如何在C#中使cmd接受箭头输入?

来自分类Dev

如何在程序继续执行的同时使代码两部分之间出现时间间隔或延迟?C ++

来自分类Dev

如何在C程序中连续检查ltrace命令输出

来自分类Dev

如何使Automa.jl接受来自stdin的输入?

来自分类Dev

使用C中的用户输入同时执行

来自分类Dev

接受\ r \ n输入C程序

来自分类Dev

接受\ r \ n输入C程序

来自分类Dev

让Rscript读取或从stdin接受输入

来自分类Dev

C 程序不会从 STDIN 读取输入

来自分类Dev

如何在单个提交输入类型上同时执行颜色框和提交动作?

来自分类Dev

如何在移动应用程序中的 webrtc 通信音频流上执行连续语音到文本

来自分类Dev

在C ++中,如何在不为每个输入分配变量的情况下接受大量输入?

来自分类Dev

如何在javascript中连续执行代码?

来自分类Dev

Linux Bash如何在需要来自stdin / files输入的程序上使用xargs?

来自分类Dev

一个可执行文件的“连续” C ++输出作为另一个程序的输入

来自分类Dev

如何将命令的连续输出重定向到用 c 编写的程序的输入

来自分类Dev

如何在定义格式的同时接受参数的 nil 值?

来自分类Dev

当Python 3接受用户输入时,如何执行函数?

来自分类Dev

如何在限制堆栈深度的同时链接许多连续的Promise?

来自分类Dev

如何在不等待换行的情况下在C中接受用户输入?

来自分类Dev

(Unix/Linux) 如何从另一个需要输入文件的 C 程序执行 C 程序?

来自分类Dev

如何在Anjuta中逐步执行C程序?

Related 相关文章

  1. 1

    我正在尝试创建一个ac程序,它将连续从stdin接受输入,直到输入exit

  2. 2

    在C中接受用户的连续输入

  3. 3

    如何在程序开始时接受输入?

  4. 4

    如何在侦听C语言中的用户输入的同时运行程序?

  5. 5

    执行程序接受线程作为输入

  6. 6

    如何在C系统/ popen命令中由另一个C ++程序连续输入?

  7. 7

    如何在拒绝浮点数和空格的同时接受整数输入?

  8. 8

    如何在C#中使cmd接受箭头输入?

  9. 9

    如何在程序继续执行的同时使代码两部分之间出现时间间隔或延迟?C ++

  10. 10

    如何在C程序中连续检查ltrace命令输出

  11. 11

    如何使Automa.jl接受来自stdin的输入?

  12. 12

    使用C中的用户输入同时执行

  13. 13

    接受\ r \ n输入C程序

  14. 14

    接受\ r \ n输入C程序

  15. 15

    让Rscript读取或从stdin接受输入

  16. 16

    C 程序不会从 STDIN 读取输入

  17. 17

    如何在单个提交输入类型上同时执行颜色框和提交动作?

  18. 18

    如何在移动应用程序中的 webrtc 通信音频流上执行连续语音到文本

  19. 19

    在C ++中,如何在不为每个输入分配变量的情况下接受大量输入?

  20. 20

    如何在javascript中连续执行代码?

  21. 21

    Linux Bash如何在需要来自stdin / files输入的程序上使用xargs?

  22. 22

    一个可执行文件的“连续” C ++输出作为另一个程序的输入

  23. 23

    如何将命令的连续输出重定向到用 c 编写的程序的输入

  24. 24

    如何在定义格式的同时接受参数的 nil 值?

  25. 25

    当Python 3接受用户输入时,如何执行函数?

  26. 26

    如何在限制堆栈深度的同时链接许多连续的Promise?

  27. 27

    如何在不等待换行的情况下在C中接受用户输入?

  28. 28

    (Unix/Linux) 如何从另一个需要输入文件的 C 程序执行 C 程序?

  29. 29

    如何在Anjuta中逐步执行C程序?

热门标签

归档