C: Shell命令无故双输出
C: Shell command double output without reason
所以我正在使用 CAN 工具
使用 this CANopenNode
我正在通过 .c 程序文件制作 candump。
我的接收器代码如下所示
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] = '[=11=]';
else if ( i>29 )
{
message_data[cdata] = raw_message[i];
cdata++;
}
}
message_data[16] = '[=11=]';
//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 的第一个插槽不是 space 时我才会这样做,因为我收到一条消息,我用 fgets 得到它,然后我得到 ' ' 然后是消息,然后 ' ' 等等继续。只有当我使用 if (isspace) 似乎有效并且如果我发表评论时,命令 "fprintf(stdout,"%s\n",raw_message);"停止工作。
我尝试了多种解决方案,但似乎没有任何效果。这样做有什么特别的原因吗?我是做错了什么还是 CANUtils 的问题?
我使用 issspace() 时的输出(输出与我 运行 candump on bash 时的输出相同){}
(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] = '[=14=]';
else if ( i>29 )
{
message_data[cdata] = raw_message[i];
cdata++;
}
}
message_data[16] = '[=14=]';
//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
问题中显示的示例数据
(1585149182.549347) vcan0 123#0801010101010101
(1585149182.550713) vcan0 123#0801010101010101
...
行长为 46 个字符,不包括换行符 ('\n'
) 或 47 个字符,包括换行符。
fgets
需要附加尾随 NUL
字符 ('[=17=]'
) 以终止字符串。这就是为什么第一次调用将读取没有换行符的行,因为缓冲区已满。缓冲区将包含字符串
"(1585149182.549347) vcan0 123#0801010101010101"
下一次调用将只读取换行符,因为这是行尾。缓冲区将包含
"\n"
您必须将 raw_message
的大小增加到至少 48。
然后你会得到
"(1585149182.549347) vcan0 123#0801010101010101\n"
一次 fgets
通话。
请注意,使用 socketcan interface 读取二进制 CAN 消息可能比解析 candump
的文本输出更好。
所以我正在使用 CAN 工具 使用 this CANopenNode 我正在通过 .c 程序文件制作 candump。
我的接收器代码如下所示
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] = '[=11=]';
else if ( i>29 )
{
message_data[cdata] = raw_message[i];
cdata++;
}
}
message_data[16] = '[=11=]';
//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 的第一个插槽不是 space 时我才会这样做,因为我收到一条消息,我用 fgets 得到它,然后我得到 ' ' 然后是消息,然后 ' ' 等等继续。只有当我使用 if (isspace) 似乎有效并且如果我发表评论时,命令 "fprintf(stdout,"%s\n",raw_message);"停止工作。 我尝试了多种解决方案,但似乎没有任何效果。这样做有什么特别的原因吗?我是做错了什么还是 CANUtils 的问题?
我使用 issspace() 时的输出(输出与我 运行 candump on bash 时的输出相同){}
(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] = '[=14=]';
else if ( i>29 )
{
message_data[cdata] = raw_message[i];
cdata++;
}
}
message_data[16] = '[=14=]';
//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
问题中显示的示例数据
(1585149182.549347) vcan0 123#0801010101010101
(1585149182.550713) vcan0 123#0801010101010101
...
行长为 46 个字符,不包括换行符 ('\n'
) 或 47 个字符,包括换行符。
fgets
需要附加尾随 NUL
字符 ('[=17=]'
) 以终止字符串。这就是为什么第一次调用将读取没有换行符的行,因为缓冲区已满。缓冲区将包含字符串
"(1585149182.549347) vcan0 123#0801010101010101"
下一次调用将只读取换行符,因为这是行尾。缓冲区将包含
"\n"
您必须将 raw_message
的大小增加到至少 48。
然后你会得到
"(1585149182.549347) vcan0 123#0801010101010101\n"
一次 fgets
通话。
请注意,使用 socketcan interface 读取二进制 CAN 消息可能比解析 candump
的文本输出更好。