我试图将两个无符号字符数组元素存储到字符串变量中。其中一个变量将包含垃圾字符,当我尝试存储时,垃圾字符不能与有效值一起存储。
这是我的代码
union u_type
{
unsigned int IntVar;
unsigned char Bytes[2];
} temp;
void main(void)
{
temp.IntVar = 39;
printf("%c%c",temp.Bytes[1],temp.Bytes[0]);
}
当我运行此代码cc test.c
和./a.out > tempfile
时
现在临时文件包含以下内容
^@'
我理解
temp.Bytes[1]
为^@
,temp.Bytes[0]
为'
。
我想将两个数组元素合并为一个应包含^@'
的字符串。我试过以下方式。
printf("%c%c",temp.Bytes[1],temp.Bytes[0]);
memcpy(string, &temp.Bytes[1],1);
memcpy(string,&temp.Bytes[0],1);
printf("%s",str);
现在str仅包含'
但是,我希望将此^@'
存储到字符串变量中。
答案 0 :(得分:3)
^@
是一些C函数打印空字符('\0'
)的方式。但是该字符也被视为字符串的结尾。因此它通常不会出现在printf("%s")
的输出中。角色是那里(所有正常的C字符串最后都有一个),但你必须做一些特别的事情来打印它。
答案 1 :(得分:0)
select id,
count(case when inc_or_dec = 'increase' then 1 end) increases,
count(case when inc_or_dec = 'decrease' then 1 end) decreases
from (
select id,
case
when coalesce(lead(value1) over(partition by id order by mth),value1) > value1 then 'increase'
when coalesce(lead(value1) over(partition by id order by mth),value1) < value1 then 'decrease'
when coalesce(lead(value1) over(partition by id order by mth),value1) = value1 then 'no change'
end inc_or_dec
from tablename) t
group by id
的问题是2:
memcpy
变量的第一个字节string
。第三件事我认为你错过了string
类型的小东西:
试试这个
int
输出
union u_type
{
unsigned int IntVar;
unsigned char Bytes[sizeof(int)];
}temp;
int main(void)
{
size_t i;
temp.IntVar = 39;
printf("Size of int: %zu\n", sizeof(int));
for (i=1; i<sizeof(int)+1; i++)
printf("%02X ",temp.Bytes[sizeof(int)-i]);
printf("\n");
return 0;
}
所以你应该使用c-string标准函数来完成你的工作:即4
00 00 00 27
:
sprintf
输出
#include <stdio.h>
#include <string.h>
#include <stdint.h>
union u_type
{
unsigned int IntVar;
unsigned char Bytes[sizeof(int)];
}temp;
int main(void)
{
size_t i;
char string[(sizeof(int)*2)+1] = {0};
uint8_t index = 0;
temp.IntVar = 39;
for (i=1; i<sizeof(int)+1; i++)
{
index += sprintf(&string[index], "%02X", temp.Bytes[sizeof(int)-i]);
}
printf(string);
printf("\n");
return 0;
}
请注意,我的所有代码都没有处理字节序。 你可以使用一个简单的函数来做到这一点:
00000027
答案 2 :(得分:0)
与struct
不同,当您定义union
时,所有union members
都是在同一个内存地址创建的,并且会根据成员type
< em> share 至少为联合分配的相同内存空间的一部分。当您对其中一个成员进行赋值时,它的值将放在内存中的该位置,使用该成员的数据type
的适当字节数。如果您对另一个成员(可能是另一个成员type
)进行后续分配,则会将新值放在同一位置,可能会破坏部分或之前的所有值。这是联盟的正常行为。您无法相信,在后续作业中,任何先前的作业仍然可行。因此,在写入另一个成员之后读取union
成员的值是C中未定义的行为。
重现您的方案,您创建了一个联合:
union u_type
{
unsigned int IntVar;
unsigned char Bytes[2];
} temp;
uint需要4个字节,uchar数组需要2个字节:
0 1 2 3 4 5 6 7 8 9 10111213141516171819202122232425262728293031
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
完成第一次作业后,temp.IntVar = 39
会使用值39填充内存:
0 1 2 3 4 5 6 7 8 9 10111213141516171819202122232425262728293031
|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|1|0|0|1|1|1| //decimal 39
在我的环境中,在重现此场景时,两个成员都位于内存位置0x0040AA30。查看uint成员temp.IntVar
时,我看到:
在ASCII中查看时,它恰好等于值39
。因为我的内存查看器根据正在查看的成员类型选择默认查看格式,所以它为第二个图像选择了ASCII,以显示uchar。当我强制它查看long int
中的内存时,它会变回:
所有这一切都归结为识别使用什么上下文(或什么格式)查看相同内存位置的内容,并且应始终在查看 最新分配的内容时解释该上下文会员。