我有一系列以网络字节顺序存储的结构。我想要检索它们。我怎么能这样做。
此类型的结构存储在文件中。我想遍历所有这些结构。 非常感谢任何帮助。
答案 0 :(得分:0)
您可以使用以下字节序更改函数:x
是您想要获取反向字节的整数,atomicity
是字节序的原子性,表示考虑的位数作为一个团队。一般来说是8。
unsigned int toggle_endian (unsigned int x, int atomicity)
{
unsigned int t = 0;
unsigned int mask, sft_amt;
switch (atomicity)
{
case 8:
mask = 0xff;
sft_amt = 8;
break;
case 16:
mask = 0xffff;
sft_amt = 16;
break;
default:
/* Invalid atomicity value, return 0x0 */
return 0x0;
}
while (x)
{
t <<= sft_amt;
t |= (x & mask);
x >>= sft_amt;
}
return t;
}
另请参阅:http://en.wikipedia.org/wiki/Endianness
<强> EDIT1:强>
对于需要转换为反向字节的结构或某种类型的动态大小,以下函数会有所帮助:
your_type conv_endian (your_type x)
{
your_type y;
char *arr = (char *) &x;
char *arr_conv = (char *) &y;
int n, i, j;
n = sizeof (your_type);
for (i=n-1, j=0; i>=0; i--, j++)
{
arr_conv[j] = arr[i];
}
return y;
}
使用以下驱动程序测试上述功能:
typedef struct _your_type {
unsigned int a, b;
} your_type;
test conv_endian (your_type x);
int main (void)
{
your_type x, y;
x.a = 0x12ab34cd;
x.b = 0x98ef76af;
y = conv_endian (x);
printf ("\n%x %x", x.a, x.b);
printf ("\n%x %x", y.a, y.b);
printf ("\n");
return 0;
}
<强> EDIT2:强>
/* x: base address of the memory
* n: length of the memory
*/
void reverse_endian (void *x, int n)
{
char *arr_conv, *arr, t;
arr = arr_conv = (char *) x;
arr += (n-1);
n/=2;
while (n)
{
t = *arr_conv;
*arr_conv = *arr;
*arr = t;
n--;
arr_conv++;
arr--;
}
}
答案 1 :(得分:0)
假设int
值实际上是4个字节长,那么您可以使用与此类似的代码:
enum { STRUCT_SIZE = 8 };
void data_reader(FILE *fp)
{
char buffer[STRUCT_SIZE];
struct node data;
while ((fread(buffer, sizeof(buffer), 1, fp) == 1)
{
unpack_struct(buffer, &data);
...stash the unpacked structure...
}
}
void unpack_struct(const char buffer[STRUCT_SIZE], struct node *data)
{
load_int4(&buffer[0], &data->data);
load_int4(&buffer[4], &data->length);
}
void load_int4(const char *data, int *value)
{
*value = ((((data[0] << 8 | data[1]) << 8) | data[2]) << 8) | data[3];
}
编写load_int4()
的方法不止一种,但这种方法足够紧凑,足以满足大多数用途。它可以被制成宏,或(更好)内联函数。
同样,您可以对此进行扩展以涵盖更多类型:load_int2()
,load_int8()
,可能是未签名的替代品等。您可以考虑普通int
是否是最适合使用的类型结构体;最好使用<stdint.h>
或<inttypes.h>
中的类型,例如int32_t
。
答案 2 :(得分:0)
我真的很想看到你到目前为止所写的内容。但与此同时,我假设您可以在字节序之间进行转换(如果不这样,Google可以提供大量的教程)。这使您无需从文件中读取结构。现在还不清楚我的结构中 length 的作用。现在它似乎只是常规数据,所以要读取结构,你会做类似以下的事情:
struct node
{
int data;
int length;
};
FILE* pFile = fopen( "myfile.bin" , "rb" );
if (pFile==NULL) {fputs ("File error",stderr); exit (1);}
char* buffer = (char*) malloc(sizeof(struct node));
if (buffer == NULL) {fputs ("Memory error",stderr); exit (2);}
size_t result = fread(buffer, 1, sizeof(struct node), pFile);
if (result != lSize) {fputs ("Reading error",stderr); exit (3);}
// 1- perform the conversion from one endianness to another
// 2- convert from char* to node*
node* tmp_struct = (node*)buffer;
printf("data: %d\n", tmp_struct->data);
printf("length: %d\n", tmp_struct->length);
fclose (pFile);
free (buffer);
此代码尚未经过测试,但它说明了应用程序的任务。上面的示例仅读取文件中的第一个可用结构。我会把剩下的作为你的功课。