C:Shell命令无故加倍输出

问题描述 投票:1回答:1

所以我正在使用CAN utils使用this CANopenNode即时通讯通过.c程序文件进行转储。

我的接收方代码看起来像这样

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脚本

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空间的第一个插槽没有空间导致我收到一条消息时,才使用fgets获取它,然后得到“'然后消息,然后是'”,然后继续。仅当我使用if(isspace)似乎可以工作并且在注释上添加命令“ fprintf(stdout,“%s \ n”,raw_message);“时,停止工作。我尝试了多种解决方案,但似乎无济于事。这样做有什么特殊原因吗?我是在做错什么,还是在做CANUtils?

当我使用issspace()时输出(输出与在bash上运行candump时的输出相同{}

(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

我不使用时的输出

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);
      }

  }

输出:

(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
c fgets can-bus
1个回答
1
投票

问题中显示的示例数据

(1585149182.549347) vcan0 123#0801010101010101
(1585149182.550713) vcan0 123#0801010101010101

...

行长为46个字符,不包含换行符('\n')或47个字符,包括换行符。

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

"(1585149182.549347) vcan0 123#0801010101010101"

下一个调用将仅读取换行符,因为这是该行的结尾。缓冲区将包含

"\n"

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

"(1585149182.549347) vcan0 123#0801010101010101\n"

一个fgets通话中。

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

© www.soinside.com 2019 - 2024. All rights reserved.