2012-10-09 28 views
1

我有一个结构为:C:复制#define的字符串转换成一个结构阵列

//GUID structure 
typedef struct { 
    var8 octet[16]; 
} GPTGUID_t; 

及长的#define为:

#define PTYPE_MRP_UPPER  0x4db80b5ce3c9e316ULL 
#define PTYPE_MRP_LOWER  0xae1502f02df97d81ULL 

我想UPPER部分在八位位组0复制到7和LOWER在8到15. 不幸的是,包括memcpy在内的所有尝试都失败了,并给出段错误。

我试过的东西如:

 strcpy(guid.octet[0], PTYPE_MRP_UPPER); 
     strcpy(guid.octet[8], PTYPE_MRP_LOWER); 

而且也

memcpy(guid.octet[0], PTYPE_MRP_UPPER, sizeof(PTYPE_MRP_UPPER)); 
memcpy(guid.octet[8], PTYPE_MRP_LOWER, sizeof(PTYPE_MRP_LOWER)); 

两个都失败了。请帮帮我。

正如一个侧面说明:

typedef unsigned char  var8; 
typedef unsigned short  var16; 
typedef unsigned int  var32; 

但是,我能提取单个八位字节:

memcpy(guid.octet, pHdr->partTypeGUID, sizeof(GPTGUID_t));//copy the partitionTypeGUID 
    p1 = getvar64(guid.octet[0]); 
    p2 = getvar64(guid.octet[8]); 

其中,#define getvar64(x) (*(var64*)(&x))

+4

阅读strcpy的功能。阅读memcpy的功能。特别注意签名中的类型。你的两个#defined符号是无符号长整型,而不是字符串或指针。你在做什么是无稽之谈。 –

+0

@SanJacinto:我知道那个......大声笑。我刚刚尝试了其他一切,因为memcpy在第一个实例中失败。 – kingsmasher1

回答

5

0x4db80b5ce3c9e316ULL不是一个字符串,所以strcpy对待是作为一个指针,并像它的值指向方式 wr翁。

您也不能使用strcpy,因为它复制,直到它找到一个零字节(字符'\0')。改为使用memcpy

您还没有通过指针memcpy函数,但值。你应该打开更多的警告,因为编译器将而不是喜欢它,但不足以使其明显错误。

尝试调用memcpy这样的:

unsigned long long val; 

val = PTYPE_MRP_UPPER; 
memcpy(&guid.octet[0], &val, sizeof(val)); 
val = PTYPE_MRP_LOWER; 
memcpy(&guid.octet[8], &val, sizeof(val)); 
+0

好的,那么出路是什么?即使memcpy失败! – kingsmasher1

+0

@ kingsmasher1这是因为你将'var8'和'unsigned long long'值传递给函数,而不是指针。看到我更新的答案。 –

+0

非常感谢,效果很好。 – kingsmasher1

-2

实际上是什么0x4db80b5ce3c9e316ULL和0xae1502f02df97d81ULL? 似乎你正在随机复制特定地址的数据。

顺便说一句,如果你实际处理字符串,

#define PTYPE_MRP_UPPER  "0x4db80b5ce3c9e316ULL" 
#define PTYPE_MRP_LOWER  "0xae1502f02df97d81ULL" 

应该做的伎俩。 (即使我不知道你到底想用这些值做)

+1

亲爱的上帝不,这不是答案。这些数字是数字文字。将它们转换为字符串,0x前缀和ULL后缀以及所有,然后从这些内容中进行memcpying将不可行。 – Wug

0

你可以使用一个联盟:

//GUID structure 
typedef struct { 
    union { 
     var8 octet[16]; 
     uint64_t qword[2]; 
    }; 
} GPTGUID_t; 

// This copies the bytes in native-endian order; do an endian swap if you need 
// non-native order 
guid.qword[0] = PTYPE_MRP_UPPER; 
guid.qword[1] = PTYPE_MRP_LOWER; 

注意,这是一个匿名的联盟,这是C11语言标准的一个特征,但它也在许多C89/C99编译器中作为语言扩展实现;如果你的编译器不支持这个,那么你不得不使用一个命名联合。

另外,如果您不能或不想修改GPTGUID_t定义,你只应一个复制字节是一次:

// This stores the bytes in big-endian order 
guid.octet[0] = (var8)(PTYPE_MRP_UPPER >> 56); 
guid.octet[1] = (var8)(PTYPE_MRP_UPPER >> 48); 
guid.octet[2] = (var8)(PTYPE_MRP_UPPER >> 40); 
guid.octet[3] = (var8)(PTYPE_MRP_UPPER >> 32); 
guid.octet[4] = (var8)(PTYPE_MRP_UPPER >> 24); 
guid.octet[5] = (var8)(PTYPE_MRP_UPPER >> 16); 
guid.octet[6] = (var8)(PTYPE_MRP_UPPER >> 8); 
guid.octet[7] = (var8)(PTYPE_MRP_UPPER); 
guid.octet[8] = (var8)(PTYPE_MRP_LOWER >> 56); 
guid.octet[9] = (var8)(PTYPE_MRP_LOWER >> 48); 
guid.octet[10] = (var8)(PTYPE_MRP_LOWER >> 40); 
guid.octet[11] = (var8)(PTYPE_MRP_LOWER >> 32); 
guid.octet[12] = (var8)(PTYPE_MRP_LOWER >> 24); 
guid.octet[13] = (var8)(PTYPE_MRP_LOWER >> 16); 
guid.octet[14] = (var8)(PTYPE_MRP_LOWER >> 8); 
guid.octet[15] = (var8)(PTYPE_MRP_LOWER); 
+0

@Steve:哎呀对不起,很好。 –

1

这些都不是内存部分,这些都是数字:为什么不使用面具?

int i; 
unsigned long long mask = 0xff00000000000000; 
for (i = 0; i < 8; i++) 
{ 
    guid.octet[i] = (PTYPE_MRP_UPPER & mask) >> ((7 - i) * 8); 
    guid.octet[i+8] = (PTYPE_MRP_LOWER & mask) >> ((7 - i) * 8); 
    mask >>= 8; 
} 
+0

我认为,你需要将'PTYPE_MRP_UPPER&mask'右移适当的位数,因为这会返回第一个位置上的位置。 –

+0

Duh XD对不起。 – Eregrith