510 :
デフォルトの名無しさん :
2001/03/30(金) 03:42 >>508 リトルエンディアンなら 0x78563412 だね。確かに機種依
存な方法だけど、元の質問者がビッグエンディアンと限定し
てるから、これでも良いんじゃない。
ただ、私だったら、Perl の pack, unpack みたいな関数
を実装して使う。似たような処理が出てきたときに使いまわ
せるし、コードの見通しも良くなるからね。
たとえば、こんな感じ。エラーチェックとか甘々だけど、骨
子は分かるよね?
#include <assert.h>
#include <stdio.h>
#include <stdarg.h>
char
ntoc(const int n)
{
static const char tbl[] = {
'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F',
};
assert(0 <= n && n <= 0xf);
return (tbl[n]);
};
void
unpack(const unsigned char *dat, const char *fmt, ...)
{
char *cp;
int *np;
long *lp;
int i;
unsigned int n;
va_list ap;
va_start(ap, fmt);
for (; *fmt != '\0'; ++fmt)
switch (*fmt) {
case 'c':
cp = va_arg(ap, char *);
for (i = *++fmt - '0'; i > 0; i -= 2) {
n = *dat++;
*cp++ = ntoc(n >> 4);
*cp++ = ntoc(n & 0xf);
}
break;
case 'd':
np = va_arg(ap, int *);
*np = 0;
for (i = 0; i < 2; ++i) {
*np <<= 8;
*np |= *dat++;
}
break;
case 'l':
lp = va_arg(ap, long *);
*lp = 0;
for (i = 0; i < 4; ++i) {
*lp <<= 8;
*lp |= *dat++;
}
break;
}
va_end(ap);
}
int
main(void)
{
char buf[] = { 0x30, 0x31, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc };
char c[4];
int i;
long l;
unpack(buf, "c4dl", &c[0], &i, &l);
printf("c = %.4s, i = %X, l = %lX\n", &c[0], i, l);
return (0);
}
511 :
498 :2001/03/30(金) 07:54
じゃ構造体を使う移植性のあるやつを。 #include <limits.h> struct T { char c[2]; char i[2]; char l[4]; }; long getint(const char* p, int n) { long x = (signed char)p[0]; int i; for (i = 1; i < n; ++i) { x = (x << CHAR_BIT) | (unsigned char)p[i]; } return x; } #define intof(x) getint((x), sizeof(x)) int main(void) { static const char buf[] = {0x30, 0x31, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc}; const struct T* t = (const struct T *)buf; printf("c = %.*s, i = %X, l = %lX\n", sizeof(t->c), t->c, intof(t->i), intof(t->l)); return 0; }
すまぬ。sizeof(long) > sizeof(int) な処理系でまずかったかも。 --- a.c~ Fri Mar 30 07:52:31 2001 +++ a.c Fri Mar 30 07:56:43 2001 @@ -16,12 +16,13 @@ return x; } -#define intof(x) getint((x), sizeof(x)) +#define intof(x) (int)getint((x), sizeof(x)) +#define longof(x) getint((x), sizeof(x)) int main(void) { static const char buf[] = {0x30, 0x31, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc}; const struct T* t = (const struct T *)buf; - printf("c = %.*s, i = %X, l = %lX\n", sizeof(t->c), t->c, intof(t->i), intof(t->l)); + printf("c = %.*s, i = %X, l = %lX\n", sizeof(t->c), t->c, intof(t->i), longof(t->l)); return 0; }