Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/62.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 删除存储在数组中的标志位_C_Arrays_Loops - Fatal编程技术网

C 删除存储在数组中的标志位

C 删除存储在数组中的标志位,c,arrays,loops,C,Arrays,Loops,我目前拥有存储011111110 011011111的变送器阵列 我希望接收器阵列存储0110111。我想消除所有01111110位 但我收到的是011011110。为什么我的代码只删除发射机阵列中的前0111110位 我的尝试代码如下所示: #define nosbits 23 #include<stdio.h> #include <stdlib.h> #include<stdbool.h> int main() { unsigned trans

我目前拥有存储011111110 011011111的变送器阵列 我希望接收器阵列存储0110111。我想消除所有01111110位

但我收到的是011011110。为什么我的代码只删除发射机阵列中的前0111110位

我的尝试代码如下所示:

#define nosbits 23
#include<stdio.h>
#include <stdlib.h>
#include<stdbool.h> 

int main()
{

   unsigned transmitter[nosbits] = { 0,1,1,1,1,1,1,0,0,1,1,0,1,1,1,0,1,1,1,1,1,1,0 };
   unsigned receiver[nosbits];
   int count = 0;
   int outputreceivercount = 0;
   bool flag = false;

   for (int i = 0; i < nosbits; i++)
   {

       if (transmitter[i] == 1)
       {
          count++;
       }
       else
       {
          count = 0;
       }

       receiver[outputreceivercount++] = transmitter[i];

       //After 5 consecutive 1s, if the next two bits are '10', then the flag is detected. 
       if ((transmitter[i + 1] == 1) && (transmitter[i + 2] == 0) && count == 5)
       {
           if (!(flag))
           {
              flag = true;
              i = i + 2;
              outputreceivercount = 0;
              count = 0;
           }  
        }
   }


   printf("Bitstream before removing flag bits:\n");
   for (int i = 0; i < nosbits; i++)
   {
      printf("%d", transmitter[i]);
   }
   printf("\n\n");


   printf("Bitstream after removing flag bits:\n");
   for (int i = 0; i < outputreceivercount; i++)
   {
      printf("%d", receiver[i]);
   }
   printf("\n");

   system("pause");
   return 0; 

}
#定义位23
#包括
#包括
#包括
int main()
{
无符号发射机[nosbits]={0,1,1,1,1,0,0,1,1,0,1,1,1,0,1,1,1,1,1,1,1,0};
无符号接收机[nosbits];
整数计数=0;
int outputreceivercount=0;
布尔标志=假;
for(int i=0;i
要回答您的具体问题,您需要在执行看起来是“删除”部分的操作之前检查
标志的状态-您需要在“删除”位之前将
标志设置为false。第一次检测到此类标志时,请将
标志
设置为true。然后,它将在所有后续循环中保持为真,因此您的“remove”部分将无法再次执行


更一般地说,我对您的“删除”部分有点困惑——每次检测到“标志”时,您都会从第0个元素开始覆盖
receiver
?字符串中发生了什么,例如“011111110011011101111111010101010”-您希望您的输出是什么?

实际上,您不需要“flag”变量来检测标志。 替换以下代码并查看是否有帮助

//After 5 consecutive 1s, if the next two bits are '10', then the flag is detected. 
   if ((transmitter[i + 1] == 1) && (transmitter[i + 2] == 0) && count == 5)
   {                        
        i = i + 2;      
        outputreceivercount -= (count+1);
        count = 0;      
    }
如果需要,可以对其进行更多优化。

1)如果需要以8位的倍数检测标志,最好使用字符,因此当检测到字节0x7e时,请将其删除。这适用于在仅传输8位字节的异步行中使用平面字符的情况。(您的示例数据在标志之间只有七位数据,因此我假设情况并非如此。)

2) 如果需要按位检测标志,则面临HDLC成帧问题,该问题有两部分:a)当检测到6个
1
位时检测标志,b)如果序列中有5个以上
1
位,则发射机插入
0
位(以确保透明度)。对于第二部分,您还需要删除序列5
1
位之后的第6
0
位。我不知道您是否想要这个,但是您的标志似乎非常类似于HDLC标志,假设您实际上没有研究这个协议

这个问题可以用有限自动机来解决。检测这一点的NFA等效物为:

 0,1 
,--. 
|  / 
| /  
|v  1       1       1       1       1      0 
(0)--->(1P)--->(2P)--->(3P)--->(4P)--->(5)--->(6D)
 |                                      |      _
 .                                      .     / \ 1
  \                                      \ 1  | V
   \0                                     `-->(7B)
    \
     \   1      1       1       1       1       0      
     (8)--->(9)--->(10)--->(11)--->(12)--->(13)--->(14F)
在哪里

  • ([1-4]P)
    接受状态,打印状态号中显示的
    1
    字符数,(例如,对于状态
    (3P)
    打印
    111
  • (6D)
    接受状态,打印
    11111
  • (7B)
    接受状态。检测到中断条件
  • (14F)
    接受状态。检测到标志
  • 所有其他国家都不是接受国。自动装置必须继续 匹配状态,直到无法达到更多的接受状态,才能输出 作为输出访问的最后一个接受状态的字符串(例如,如果最后一个接受状态是6D,则它必须输出“11111”。如果访问的最后一个状态包括多个接受状态,则优先级顺序为:

    14F, 7B, 6D, 4P, 3P, 2P, 1P
    
这个NFA识别8种字符串(我将它们表示为regexp),即:
0
01111110
1
11
111
1111
11111 0
,和
11111111*
。如果接受标志,您还必须检查位数是否为8的倍数,因为您可以使用此协议拥有任意位序列。可能您没有,因为samp您发布的le数据仅包含七位。它可以由以下
lex(1)
模式表示:

%%
0         ECHO; 
01111110  putchar('F');
1111111*  putchar('B');
1         |
11        |
111       |
1111      ECHO;
111110    fputs("11111", stdout);
.         ;
%%
注 下面是一个完整的DFA,它将输入位转换为 字母表(对于您的问题,只需将
“F”
“B”
字符串替换为空字符串
“”
):

或者,如果要调试自动机工作方式的跟踪,请使用

cc -o hdlc_enc -DDEBUG=1 hdlc.c
ln hdlc_enc hdlc_dec
您将使用两个命令对标准输入进行编码
hdlc_enc
,并使用
hdlc_dec
对其进行解码。要编码,请使用
F
作为标志,
B
作为中断,
0
1
(无限制)它将在适当的位置插入
0
。要解码,只需输入一个位序列,它将把标志转换为
F
,分解为
B
,并消除编码器插入的虚假
0
。(插入五个
1
位后,插入a
0
,以确保透明度)

我手工编译了这个自动机,所以它的状态数可能不是最优的,但是18个状态并不太多

状态名称代表前缀
ST
,后跟读得太远而尚未输出的内容,因为我们无法确定它是标志、中断还是简单的数据位序列。锚定到流开头的状态是
cc -o hdlc_enc hdlc.c
ln hdlc_enc hdlc_dec
cc -o hdlc_enc -DDEBUG=1 hdlc.c
ln hdlc_enc hdlc_dec