C - 理解结构的值设置模式

时间:2013-12-30 22:23:03

标签: c memory structure

我已经建立了一个小型的c程序,我试图设置一个结构值

**static faut fautData**

typedef struct
{
    char ds[25];
    char ec[51];
    char vc[51];
    char rc[51];
    char rb[2];
    char eb[2];
    char vb[2];
    char es[10];
    char dias[50];
    char ss[10];
} faut;

我有一个函数名称更新来设置上面指定结构的值

但是当我尝试设置** faut.es ** @更新功能的开头时,该值不会被分配(在我的打印调用中它没有得到反映。

当我设置相同的值@结束时,我能够打印输出并看到值

为什么会这样?

示例代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct
{
    char ds[25];
    char ec[51];
    char vc[51];
    char rc[51];
    char rb[2];
    char eb[2];
    char vb[2];
    char es[10];
    char dias[50];
    char ss[10];
} faut;


typedef struct
{
    unsigned int d5;
    unsigned int d10;
    unsigned int d20;
    unsigned int d50;
    unsigned int d100;
    unsigned int d500;
    unsigned int d1000;
    unsigned int an;
    unsigned int rn;
    unsigned int cn;
    int alr;

}ncd;

static ncd chkncd;
int cdc;

void admin_init(void)
{
    char Keys[17];
    int i = 0;
    int keysEnabled;
    int shift = 0x01;
    keysEnabled=0xFF;
    strcpy(Keys,"0000000000000000");
    //keysEnabled = getKeysToEnable();
    for(i=0;i<8;i++)
    {

        switch((keysEnabled & shift))
        {
            case 0x10:
                Keys[0]=0x34;
                Keys[1]=0x36;
                break;
            case 0x20:
                Keys[2]=0x34;
                Keys[3]=0x37;
                break;
            case 0x40:
                Keys[4]=0x34;
                Keys[5]=0x38;
                break;
            case 0x80:
                Keys[6]=0x34;
                Keys[7]=0x39;
                break;

            case 0x08:
                Keys[8]=0x34;
                Keys[9]=0x34;
                break;
            case 0x04:
                Keys[10]=0x34;
                Keys[11]=0x33;
                break;
            case 0x02:
                Keys[12]=0x34;
                Keys[13]=0x32;
                break;
            case 0x01:
                Keys[14]=0x34;
                Keys[15]=0x31;
                break;
            default:
                break;
        }
        shift = shift << 1;
    }
    printf("%s",Keys);

}

void update(void)
{
    char temp[512];
    int i = 0;
    static faut fautData;
    memset(&fautData, '\0', sizeof(fautData));
    int cat =0;
    if(cat) // Any failure
    {
        strncpy(fautData.ds, "3", 1);
        strncpy(fautData.es, "4", 1);
        memset(temp,'\0',sizeof(temp));
    }
    else
    {
        strncpy(fautData.es, "2",1);
        strncpy(fautData.ds, "0",2);
    }
    strcpy(&fautData.ec[0],"00000000000000000000000000000000000000000000000000");//00000000000000000000000000000000000000000000000000
    strcpy(&fautData.rc[0],"00000000000000000000000000000000000000000000000000");//00000000000000000000000000000000000000000000000000
    strcpy(fautData.vc,"");
    if(chkncd.d50 != 0){
        memset(temp,'\0',sizeof(temp));
        strcat(fautData.vc,"01");
        sprintf(temp, "%03d", chkncd.d50);
        strcat(fautData.vc,temp);
    }
    if(chkncd.d100 != 0){
        memset(temp,'\0',sizeof(temp));
        strcat(fautData.vc,"02");
        sprintf(temp, "%03d", chkncd.d100);
        strcat(fautData.vc,temp);
    }

    if(chkncd.d500 != 0){
        memset(temp,'\0',sizeof(temp));
        strcat(fautData.vc,"03");
        sprintf(temp, "%03d", chkncd.d500);
        strcat(fautData.vc,temp);
    }
    if(chkncd.d1000 != 0){
        memset(temp,'\0',sizeof(temp));
        strcat(fautData.vc,"04");
        sprintf(temp, "%03d", chkncd.d1000);
        strcat(fautData.vc,temp);
    }
    sprintf(fautData.vb, "%02d", chkncd.an);
    fautData.rb[0] = 0x30;
    fautData.rb[1] = 0x30;
    fautData.eb[0] = 0x30;
    fautData.eb[1] = 0x30;
    strncpy(fautData.dias, "0", 1);
    cdc = cdc - chkncd.an - chkncd.cn;
    if ((chkncd.alr) || (cdc < 2450))
        strncpy(fautData.ss, "4", 1);
    else
        strncpy(fautData.ss, "1", 1);
    sprintf(temp,"keysEnabled:\nds : %s\nec : %s\n vc : %s\nrc : %s\n rb : %s\n eb : %s\n vb : %s\n es : %s\n ss : %s\n",   fautData.ds,    fautData.ec,    fautData.vc,    fautData.rc,    fautData.rb,    fautData.eb,    fautData.vb,    fautData.es,    fautData.dias,  fautData.ss);
    printf("%s",temp);
}



int main(void) {

    cdc=2300;
    chkncd.d5=0;
    chkncd.d10=0;
    chkncd.d20=0;
    chkncd.d50=0;
    chkncd.d100=0;
    chkncd.d500=1;
    chkncd.d1000=0;
    chkncd.alr=0;
    chkncd.an=1;
    chkncd.rn=0;
    chkncd.cn=0;
    update();
    return EXIT_SUCCESS;
}

2 个答案:

答案 0 :(得分:2)

你的问题在这里:

sprintf(fautData.vb, "%02d", chkncd.an);

fautData.vb是两个字节,但是您的sprintf调用将写入三个字节:两位数后跟一个空终止符,它会溢出vb数组并覆盖{{1 }}

答案 1 :(得分:1)

当你这样做时

strncpy(fautData.es, "2",1);

你正在复制“最多1个字符”。这使您没有终止null,这可能会导致问题。正如描述所说:

  

如果,目的地末尾没有隐式附加空字符   source长于num。因此,在这种情况下,目的地不应   被认为是一个空终止的C字符串(如此读取它   溢出)。

你需要做

strncpy(fautData.es, "2",2);

确保您拥有有效的字符串。

此外,在你的行

sprintf(fautData.vb, "%02d", chkncd.an);

你在'\0'之后加.vb(所以你真的写了三个字符)。但由于vb只有两个字符的空格,因此nul将作为下一个结构元素的第一个元素 - 恰好是.es。因此,当您尝试打印.es时,第一个字符是“字符串结束”,并且不会打印任何内容。

如果您将struct更改为vb的三个空格元素:

char vb[3];
问题消失了。

这一直是一件棘手的事情;每个字符串需要多一个空格,而不是“字符”。 '\0'需要空间......

更新,因为你说你被限制为有两个字节,你必须限制自己在写作期间只打印两个字符到结构元素 - 你必须限制自己只打印两个打印过程中的字符例如:

void set_vb(int value) {
  char temp[3];
  sprintf(temp, "%02d", value);
  memcpy(fautData.vb, temp, 2);
}

void print_vb(void {
  printf("%.2s", fautData.vb);
}

现在您可以忘记“如何正确操作”,并在需要设置或打印vb的值时调用这两个函数。您可以对遇到此问题的其他元素执行相同操作(考虑到结构的大小,可能适用于其中许多元素......)