首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C: Shell命令无缘无故地重复输出

C: Shell命令无缘无故地重复输出
EN

Stack Overflow用户
提问于 2020-03-25 14:37:21
回答 1查看 133关注 0票数 1

因此,im与CAN一起使用,CANopenNode,im,通过.c程序文件制作烛台。

我的接收器代码如下所示

代码语言:javascript
复制
char raw_message[47], message_id[4], message_data[17];
fp = popen("candump vcan0 -L", "r");

  if( fp == NULL )
  {
    printf("Failed to run CANDUMP for VCAN0");
    exit(1);
  }

  while ( fgets(raw_message, sizeof(raw_message), fp) )
  {
      if( isspace(raw_message[0]) )
      {
      }
      else
      {
        //GETTING THE ACTUAL MESSAGE = ID+DATA
        cid = 0;
        cdata = 0;
        for(i=26; i<46; i++)
        {
          if( i<29 )
          {
            message_id[cid] = raw_message[i];
            cid++;
          }
          else if ( i==29 )
            message_id[cid] = '\0';
          else if ( i>29 )
          {
            message_data[cdata] = raw_message[i];
            cdata++;
          }
        }
        message_data[16] = '\0';
        //END OF GETTING MESSAGE
        fprintf(stdout,"%s\n",raw_message); 
        fflush(stdout);
      }

  }

  pclose(fp);

和我运行一个shell脚本来发送

代码语言:javascript
复制
echo "Start"
i=0;
while [ $i -le 5 ] ;
do
    #echo "sent"
    cansend vcan0 123#0801010101010101
    let i=$i+1
done
exit 0

我想要做的是将id从消息的实际数据中分离出来。问题是,正如你所看到的,只有在raw_message的第一个插槽不是空格的情况下,我才会这样做,因为我收到一条消息,我用fget得到它,然后我得到‘’然后消息,然后‘然后继续。只有当我使用if (isspace)时,如果我添加注释,命令"fprintf(stdout,"%s\n",raw_message)就停止工作了。我尝试了多种解决方案,但似乎没有任何效果。有什么特别的原因吗?我是做错了什么,还是做错了CANUtils?

使用issspace()时输出(输出与在bash上运行烛台时相同){}

代码语言:javascript
复制
(1585149182.549347) vcan0 123#0801010101010101
(1585149182.550713) vcan0 123#0801010101010101
(1585149182.555930) vcan0 123#0801010101010101
(1585149182.559413) vcan0 123#0801010101010101
(1585149182.560687) vcan0 123#0801010101010101
(1585149182.561604) vcan0 123#0801010101010101

当我不使用它时输出

代码语言:javascript
复制
while ( fgets(raw_message, sizeof(raw_message), fpdump) )
  {
      // if( isspace(raw_message[0]) )
      // {
      // }
      // else
      {
        //GETTING THE ACTUAL MESSAGE = ID+DATA
        cid = 0;
        cdata = 0;
        for(i=26; i<46; i++)
        {
          if( i<29 )
          {
            message_id[cid] = raw_message[i];
            cid++;
          }
          else if ( i==29 )
            message_id[cid] = '\0';
          else if ( i>29 )
          {
            message_data[cdata] = raw_message[i];
            cdata++;
          }
        }
        message_data[16] = '\0';
        //END OF GETTING MESSAGE
        fprintf(stdout,"%s\n",raw_message); 
        fflush(stdout);
      }

  }

输出:

代码语言:javascript
复制
(1585149305.257591) vcan0 123#0801010101010101


(1585149305.258339) vcan0 123#0801010101010101


(1585149305.259055) vcan0 123#0801010101010101


(1585149305.259651) vcan0 123#0801010101010101


(1585149305.260280) vcan0 123#0801010101010101


(1585149305.260860) vcan0 123#0801010101010101
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-03-25 16:11:19

如问题中所示的示例数据

代码语言:javascript
复制
(1585149182.549347) vcan0 123#0801010101010101
(1585149182.550713) vcan0 123#0801010101010101

..。

行长度为46个字符,没有换行符('\n')或包括换行符在内的47个字符。

fgets需要追加一个尾随NUL字符('\0')来终止字符串。这就是为什么第一个调用将在没有换行符的情况下读取该行,因为缓冲区已满。缓冲区将包含字符串。

代码语言:javascript
复制
"(1585149182.549347) vcan0 123#0801010101010101"

下一次调用只会读取换行符,因为这是行的末尾。缓冲区将包含

代码语言:javascript
复制
"\n"

您必须将raw_message的大小增加到至少48。那你就会得到

代码语言:javascript
复制
"(1585149182.549347) vcan0 123#0801010101010101\n"

在一个fgets电话里。

注意,最好使用socketcan接口来读取二进制CAN消息,而不是解析candump的文本输出。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60851068

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档