C 执行循环冗余检查的程序出错

C 执行循环冗余检查的程序出错,c,C,我尝试在c中实现crc。我的逻辑不是很好。我尝试的是将消息(msg)复制到一个temp变量中,最后我添加了比crc除数div中的位数少1的零数 例如: msg=11010011101100 div=1011 然后温度变为: temp=11010011101100000 div= 10110000000000000 查找temp和div的异或并将其存储在temp中 给出temp=01100011101100000计算temp第一个“1”之前出现的零的数量,并将div的字符右移到该数字,然后重复

我尝试在c中实现crc。我的逻辑不是很好。我尝试的是将消息(msg)复制到一个temp变量中,最后我添加了比crc除数div中的位数少1的零数

例如:

msg=11010011101100
div=1011
然后温度变为:

temp=11010011101100000
div= 10110000000000000
查找temp和div的异或并将其存储在temp中

给出
temp=01100011101100000
计算temp第一个“1”之前出现的零的数量,并将div的字符右移到该数字,然后重复相同的过程,直到temp的十进制值小于div的十进制值。这将给出余数

我的问题是,当我在temp的末尾附加0时,它会存储0以及一些特殊字符,如:

temp=11010011101100000$#UFI#->Jp#|
当我调试时,我发现了一个错误

浮点:堆栈下溢

这是我的密码:

#include<stdio.h>
#include<conio.h>
#include<math.h>
#include<string.h>

void main() {
    char msg[100],div[100],temp[100];
    int i,j=0,k=0,l=0,msglen,divlen,newdivlen,ct=0,divdec=0,tempdec=0;

    printf("Enter the message\n");
    gets(msg);
    printf("\nEnter the divisor\n");
    gets(div);

    msglen=strlen(msg);
    divlen=strlen(div);
    newdivlen=msglen+divlen-1;

    strcpy(temp,msg);

    for(i=msglen;i<newdivlen;i++)
        temp[i]='0';
    printf("\nModified Temp:");
    printf("%s",temp);

    for(i=divlen;i<newdivlen;i++)
        div[i]='0';
    printf("\nModified div:");
    printf("%s",div);

    for(i=newdivlen;i>0;i--)
        divdec=divdec+div[i]*pow(2,j++);

    for(i=newdivlen;i>0;i--)
        tempdec=tempdec+temp[i]*pow(2,k++);

    while(tempdec>divdec)
    {
        for(i=0;i<newdivlen;i++)
        {
            temp[i]=(temp[i]==div[i])?'0':'1';
            while(temp[i]!='1')
                ct++;
        }

        for(i=newdivlen+ct;i>ct;i--)
            div[i]=div[i-ct];

        for(i=0;i<ct;i++)
            div[i]='0';

        tempdec=0;

        for(i=newdivlen;i>0;i--)
            tempdec=tempdec+temp[i]*pow(2,l++);
    }
    printf("%s",temp);
    getch();
}

给出错误浮点:堆栈下溢

问题是您在NUL终止符上写入了一个
0
,并且没有在字符串上放置另一个NUL终止符。因此,
printf
变得混乱,打印垃圾。也就是说这个代码

for(i=msglen;i<newdivlen;i++)
    temp[i]='0';
printf("\nModified Temp:");
printf("%s",temp);

for(i=msglen;i必须使用整数

int CRC(unsigned int n);
int CRC_fast(unsigned int n);
void printbinary(unsigned int n);
unsigned int msb(register unsigned int n);

int main()
{
    char buf[5];
    strcpy(buf, "ABCD");

    //convert string to number, 
    //this is like 1234 = 1*1000 + 2*100 + 3*10 + 4, but with hexadecimal
    unsigned int n = buf[3] * 0x1000000 + buf[2] * 0x10000 + buf[1] * 0x100 + buf[3];

    /*
    - "ABCD" becomes just a number
    - Any string of text can become a sequence of numbers
    - you can work directly with numbers and bits
    - shift the bits left and right using '<<' and '>>' operator
    - use bitwise operators & | ^
    - use basic math with numbers
    */

    //finding CRC, from Wikipedia example: 

    n = 13548; // 11010011101100 in binary (14 bits long), 13548 in decimal

    //padding by 3 bits: left shift by 3 bits:
    n <<= 3; //11010011101100000 (now it's 17 bits long)

    //17 is "sort of" the length of integer, can be obtained from 1 + most significant bit of n
    int m = msb(n) + 1;
    printf("len(%d) = %d\n", n, m); 

    int divisor = 11; //1011 in binary (4 bits) 

    divisor <<= (17 - 4);

    //lets see the bits:
    printbinary(n);
    printbinary(divisor);

    unsigned int result = n ^ divisor;// XOR operator
    printbinary(result);

    //put this in function:
    n = CRC(13548);

    n = CRC_fast(13548);

    return 0;
}

void printbinary(unsigned int n)
{
    char buf[33];
    memset(buf, 0, 33);
    unsigned int mask = 1 << 31;
    //result in binary: 1 followed by 31 zero

    for (int i = 0; i < 32; i++)
    {
        buf[i] = (n & mask) ? '1' : '0';

        //shift the mask by 1 bit to the right
        mask >>= 1;
        /*
        mask will be shifted like this:
        100000... first
        010000... second
        001000... third
        */
    }

    printf("%s\n", buf);
}

//find most significant bit
unsigned int msb(register unsigned int n)
{
    unsigned i = 0;
    while (n >>= 1)
        i++;
    return i;
}

int CRC(unsigned int n)
{
    printf("\nCRC(%d)\n", n);
    unsigned int polynomial = 11;
    unsigned int plen = msb(polynomial);
    unsigned int divisor;

    n <<= 3;

    for (;;)
    {
        int shift = msb(n) - plen;
        if (shift < 0) break;
        divisor = polynomial << shift;

        printbinary(n);
        printbinary(divisor);
        printf("-------------------------------\n");
        n ^= divisor;
        printbinary(n);
        printf("\n");
    }

    printf("result: %d\n\n", n);

    return n;
}

int CRC_fast(unsigned int n)
{
    printf("\nCRC_fast(%d)\n", n);
    unsigned int polynomial = 11;
    unsigned int plen = msb(polynomial);
    unsigned int divisor;

    n <<= 3;

    for (;;)
    {
        int shift = msb(n) - plen;
        if (shift < 0) break;
        n ^= (polynomial << shift);
    }

    printf("result: %d\n\n", n);

    return n;
}
字符串方法以前的问题: 这个太让人困惑了:

for (i = newdivlen + ct; i > ct; i--)
    div[i] = div[i - ct];
我不知道什么是
ct
。for
循环的
都是反向的,这使得代码有时更快(可能快1纳秒),但这让它非常混乱

还有一个while循环

while (tempdec > divdec)
{
    //...
}

如果你没有得到预期的结果,这种情况可能会一直持续下去。这使得调试代码变得非常困难。

这个网站上已经有很多C语言的CRC代码。或者你想自己做吗?例如,我想自己做。请帮我理解浮点:堆栈下溢,但这不是div的问题[]它没有显示任何垃圾值。请告诉我为什么?@prak有时你会很幸运。也许
div[]
数组一开始就满是零。你可以用
打印整个数组来查看(i=0;我知道我的逻辑不正确,它与crc无关,但在干运行时,它给出了输出。但当我编译时,它给出了错误。请帮助如果你第一次这样做正确,你会节省很多时间。处理字符串,转换为位,需要花费太长时间。将字符串转换为整数更容易,然后你可以处理d直接使用位。我更新了示例以显示如何使用整数和位,并以二进制形式打印出值。
while (temp[i] != '1')
{
    ct++;
}
for (i = newdivlen + ct; i > ct; i--)
    div[i] = div[i - ct];
while (tempdec > divdec)
{
    //...
}