我已经建立了一个小型的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;
}
答案 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
的值时调用这两个函数。您可以对遇到此问题的其他元素执行相同操作(考虑到结构的大小,可能适用于其中许多元素......)