Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #18453 > unrolled thread

Write int as a 4 byte big-endian to file.

Started byMS <ms@no_spam_thanks.com>
First post2012-03-10 18:00 +0000
Last post2012-03-11 21:45 +0000
Articles 20 on this page of 46 — 23 participants

Back to article view | Back to comp.lang.c


Contents

  Write int as a 4 byte big-endian to file. MS <ms@no_spam_thanks.com> - 2012-03-10 18:00 +0000
    Re: Write int as a 4 byte big-endian to file. Don Y <this@isnotme.com> - 2012-03-10 11:11 -0700
      Re: Write int as a 4 byte big-endian to file. MS <ms@no_spam_thanks.com> - 2012-03-10 18:36 +0000
        Re: Write int as a 4 byte big-endian to file. Stephen Sprunk <stephen@sprunk.org> - 2012-03-10 14:09 -0600
          Re: Write int as a 4 byte big-endian to file. Keith Thompson <kst-u@mib.org> - 2012-03-10 14:06 -0800
            Re: Write int as a 4 byte big-endian to file. Stephen Sprunk <stephen@sprunk.org> - 2012-03-10 21:53 -0600
        Re: Write int as a 4 byte big-endian to file. Eric Sosman <esosman@ieee-dot-org.invalid> - 2012-03-10 15:20 -0500
          Re: Write int as a 4 byte big-endian to file. Eric Sosman <esosman@ieee-dot-org.invalid> - 2012-03-10 15:22 -0500
    Re: Write int as a 4 byte big-endian to file. Bl0ckeduser <bl0ckedusersoft@gmail.com> - 2012-03-10 14:42 -0500
      Re: Write int as a 4 byte big-endian to file. Bl0ckeduser <bl0ckedusersoft@gmail.com> - 2012-03-10 16:33 -0500
        Re: Write int as a 4 byte big-endian to file. Malcolm McLean <malcolm.mclean5@btinternet.com> - 2012-03-10 13:46 -0800
      Re: Write int as a 4 byte big-endian to file. Joe Pfeiffer <pfeiffer@cs.nmsu.edu> - 2012-03-10 17:42 -0700
        Re: Write int as a 4 byte big-endian to file. Bl0ckeduser <bl0ckedusersoft@gmail.com> - 2012-03-10 22:53 -0500
    Re: Write int as a 4 byte big-endian to file. Tim Rentsch <txr@alumni.caltech.edu> - 2012-03-10 11:44 -0800
      Re: Write int as a 4 byte big-endian to file. "Morris Keesan" <mkeesan@post.harvard.edu> - 2012-03-10 17:18 -0500
        Re: Write int as a 4 byte big-endian to file. Ike Naar <ike@iceland.freeshell.org> - 2012-03-10 23:00 +0000
        Re: Write int as a 4 byte big-endian to file. Tim Rentsch <txr@alumni.caltech.edu> - 2012-03-11 13:08 -0700
          Re: Write int as a 4 byte big-endian to file. tom st denis <tom@iahu.ca> - 2012-03-12 05:56 -0700
            Re: Write int as a 4 byte big-endian to file. jacob navia <jacob@spamsink.net> - 2012-03-13 00:01 +0100
              Re: Write int as a 4 byte big-endian to file. gwowen <gwowen@gmail.com> - 2012-03-13 00:55 -0700
                Re: Write int as a 4 byte big-endian to file. Ike Naar <ike@sverige.freeshell.org> - 2012-03-13 09:56 +0000
                Re: Write int as a 4 byte big-endian to file. Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-03-13 12:26 +0000
                Re: Write int as a 4 byte big-endian to file. Tim Rentsch <txr@alumni.caltech.edu> - 2012-03-13 16:04 -0700
            Re: Write int as a 4 byte big-endian to file. Tim Rentsch <txr@alumni.caltech.edu> - 2012-03-13 15:54 -0700
    Re: Write int as a 4 byte big-endian to file. Sjouke Burry <s@b> - 2012-03-10 19:44 +0000
      Re: Write int as a 4 byte big-endian to file. "Morris Keesan" <mkeesan@post.harvard.edu> - 2012-03-10 17:21 -0500
    Re: Write int as a 4 byte big-endian to file. "Morris Keesan" <mkeesan@post.harvard.edu> - 2012-03-10 14:57 -0500
      Re: Write int as a 4 byte big-endian to file. Ike Naar <ike@iceland.freeshell.org> - 2012-03-10 21:17 +0000
        Re: Write int as a 4 byte big-endian to file. "Morris Keesan" <mkeesan@post.harvard.edu> - 2012-03-10 17:22 -0500
    Re: Write int as a 4 byte big-endian to file. Lew Pitcher <lpitcher@teksavvy.com> - 2012-03-10 15:55 -0500
    Re: Write int as a 4 byte big-endian to file. Geoff <geoff@invalid.invalid> - 2012-03-10 13:01 -0800
      Re: Write int as a 4 byte big-endian to file. Stephen Sprunk <stephen@sprunk.org> - 2012-03-10 22:01 -0600
        Re: Write int as a 4 byte big-endian to file. Malcolm McLean <malcolm.mclean5@btinternet.com> - 2012-03-11 00:36 -0800
      Re: Write int as a 4 byte big-endian to file. "io_x" <a@b.c.invalid> - 2012-03-13 12:29 +0100
        Re: Write int as a 4 byte big-endian to file. "io_x" <a@b.c.invalid> - 2012-03-13 13:14 +0100
    Re: Write int as a 4 byte big-endian to file. Malcolm McLean <malcolm.mclean5@btinternet.com> - 2012-03-10 12:39 -0800
      Re: Write int as a 4 byte big-endian to file. "Morris Keesan" <mkeesan@post.harvard.edu> - 2012-03-10 17:29 -0500
        Re: Write int as a 4 byte big-endian to file. Malcolm McLean <malcolm.mclean5@btinternet.com> - 2012-03-10 15:02 -0800
          Re: Write int as a 4 byte big-endian to file. "Morris Keesan" <mkeesan@post.harvard.edu> - 2012-03-11 18:26 -0400
    Re: Write int as a 4 byte big-endian to file. Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-03-10 21:12 +0000
    Re: Write int as a 4 byte big-endian to file. jgk@panix.com (Joe keane) - 2012-03-11 21:29 +0000
      Re: Write int as a 4 byte big-endian to file. Ian Collins <ian-news@hotmail.com> - 2012-03-12 10:34 +1300
        Re: Write int as a 4 byte big-endian to file. jgk@panix.com (Joe keane) - 2012-03-12 21:37 +0000
          Re: Write int as a 4 byte big-endian to file. Keith Thompson <kst-u@mib.org> - 2012-03-12 23:40 -0700
            Re: Write int as a 4 byte big-endian to file. Kaz Kylheku <kaz@kylheku.com> - 2012-03-13 07:11 +0000
      Re: Write int as a 4 byte big-endian to file. Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-03-11 21:45 +0000

Page 2 of 3 — ← Prev page 1 [2] 3  Next page →


#18658

FromIke Naar <ike@sverige.freeshell.org>
Date2012-03-13 09:56 +0000
Message-ID<slrn3vfsjlu6e5.nro.ike@sverige.freeshell.org>
In reply to#18647
On 2012-03-13, gwowen <gwowen@gmail.com> wrote:
[about

  bytes[i] = what % 256,  what /= 256;

]

> Clever people do not write code like that.  Clever people *can* write
> code like that, but are clever enough not to, because they understand
> maintainance burdens, and why code clarity beats code cleverness in
> 99.9999% of cases.

There can be a good reason to write code like that.
Suppose we have variables x and y that represent the position
of a bishop on a chess board. The piece is currently on
a black square, and this is an invariant according to the rules
of the game. No legal move can put it on a white square.
Now we move it from (x, y) (black square) to (x+3, y-3) (black square).

It could be written like this:

    /* initial: black square */
  x = x+3;
    /* intermediate: white square */
  y = y-3;
    /* final: black square */

but the intermediate state violates the invariant and that's ugly.
It would be cleaner to write it like this (using Python-like multiple
assignment):

    /* initial: black square */
  x, y  =  x+3, y-3;
    /* final: black square */

and avoid the invalid intermediate state.
Of course C does not have multiple assignment, but this comes close:

    /* initial: black square */
  x = x+3, y = y-3;
    /* final: black square */

I think here the use of a comma expression leads to somewhat cleaner
code: the fact that it's a single statement shows the intention
to make one legal move, instead of two illegal moves that combine
into a legal move.

[toc] | [prev] | [next] | [standalone]


#18671

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2012-03-13 12:26 +0000
Message-ID<0.187dbdad36ff8111b64e.20120313122602GMT.87mx7k7kmd.fsf@bsb.me.uk>
In reply to#18647
gwowen <gwowen@gmail.com> writes:

> On Mar 12, 11:01 pm, jacob navia <ja...@spamsink.net> wrote:
>
>> I can fully understand why you do not like clever people.
>
> Clever people do not write code like that.  Clever people *can* write
> code like that, but are clever enough not to, because they understand
> maintainance burdens, and why code clarity beats code cleverness in
> 99.9999% of cases.

I fully agree about clarity, but how unclear was the code and in what
way?  I don't like the idea of avoiding parts of the language because
some future reader might not might not know it.  For one thing, where do
you draw the line?  Who decides what's generally well understood?  But
my real objection is that the lack of clarity is superficial -- a quick
look on the web, or a check in a book and everything becomes clear again.

When I was, however briefly, doing this sort of maintenance, I never
minded that sort of "clever" code.  Seeing a neat way to write something
made a dull job a little more interesting.  I really don't ever recall
making a mistake because of a syntactic misunderstanding, nor do recall
being significantly impeded by such a thing.

All of the hard maintenance problems I recall came from trying to
understand the dynamic behaviour of a program.  The most obvious example
in C is whether allocated memory is used after it's lifetime has ended,
but there are lots of other.  The worst I ever saw was an old Unix sort
utility which passed pointers around without the proper conversions.  It
was almost impossible to tell if the pointer you had at some point was
really a char pointer or a struct pointer and, because this was a
word-addressed machine, that mattered.  It took weeks to get it running
and I very much doubt I got all the bugs out even then.  I would have
happily traded a thousand uses of the most obscure C syntax for a
clearer and better organised program.

On the use of the comma operator, I agree with Tim that it's useful when
the purpose of the expressions are closely related.  I use it,
for example, when a function "returns" more than one thing:

      return *reason = ZERO_DIVIDE, FAIL;

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#18726

FromTim Rentsch <txr@alumni.caltech.edu>
Date2012-03-13 16:04 -0700
Message-ID<kfnfwdcm7br.fsf@x-alumni2.alumni.caltech.edu>
In reply to#18647
gwowen <gwowen@gmail.com> writes:

> On Mar 12, 11:01 pm, jacob navia <ja...@spamsink.net> wrote:
>
>> I can fully understand why you do not like clever people.
>
> Clever people do not write code like that.  Clever people *can* write
> code like that, but are clever enough not to, because they understand
> maintainance burdens, and why code clarity beats code cleverness in
> 99.9999% of cases.

The case in question was purely an issue of coding style.  Some
people (I happen to be one of them) think the particular style
used improves clarity, not reduces it.  If someone prefers a
different style, I'm okay with that.  But I wouldn't call it
"clever" or "not clever", just a different style.

[toc] | [prev] | [next] | [standalone]


#18724

FromTim Rentsch <txr@alumni.caltech.edu>
Date2012-03-13 15:54 -0700
Message-ID<kfnk42om7ru.fsf@x-alumni2.alumni.caltech.edu>
In reply to#18577
tom st denis <tom@iahu.ca> writes:

> On Mar 11, 4:08 pm, Tim Rentsch <t...@alumni.caltech.edu> wrote:
>> "Morris Keesan" <mkee...@post.harvard.edu> writes:
>> > On Sat, 10 Mar 2012 14:44:13 -0500, Tim Rentsch
>> > <t...@alumni.caltech.edu>  wrote:
>>
>> >>     for(  i = 3;  i >= 0;  i--  )  bytes[i] = what % 256,  what /= 256;
>>
>> > What ???  Did you do this with a comma operator just to make it hard
>> > to read?
>>
>> No, I used a comma operator because I think of the two assignments
>> as a single conceptual unit (extract the low order bits and shift
>> those bits out of the word being worked on), so it seems natural
>> to express that conceptual unit as a single statement.
>
> If you worked under me I'd make you re-write that code properly.
> "Clever" people tend to write code that holds up less under the test
> of time.

If you worked under me you would learn that different
groups have rather different ideas about what constitutes
good or readable coding style, and it's better not to
be so dogmatic about it.  But then neither one of those
hypotheticals holds, does it?  :)

[toc] | [prev] | [next] | [standalone]


#18467

FromSjouke Burry <s@b>
Date2012-03-10 19:44 +0000
Message-ID<XnsA012D2FFF6B56sjoukeburrysoesterbe@213.75.12.10>
In reply to#18453
MS <ms@no_spam_thanks.com> wrote in news:mFM6r.21733$di4.7072
@newsfe14.ams2:

> Hi,
> 
> I need some help with something which is a little over my pay grade. :)
> 
> The file which I must write has a header followed by a sequence of ints 
> each of which must be written as a 4 byte big-endian.
> 
> The comp.lang.c has advice on finding out whether your machine is 
> little-endian or big-endian (little-endian in my case) but not on how 
to 
> do the kind of operation I need to do.
> 
> I am sorry to say that I simply have no idea whatsoever how to write an 
> int to a file as a 4 byte big-endian. Can someone show me how please?
> 
> Many thanks.
> 
Hm... just reverse the routine below....

int little_endian(char *c){
	static union{
		int k;
		char c[4];
	}p;
	p.c[0]=c[3];
	p.c[1]=c[2];
	p.c[2]=c[1];
	p.c[3]=c[0];
	return p.k;
}

[toc] | [prev] | [next] | [standalone]


#18488

From"Morris Keesan" <mkeesan@post.harvard.edu>
Date2012-03-10 17:21 -0500
Message-ID<op.way61bnq5qv6o3@toshiba-laptop>
In reply to#18467
On Sat, 10 Mar 2012 14:44:38 -0500, Sjouke Burry <s@b> wrote:

> MS <ms@no_spam_thanks.com> wrote in news:mFM6r.21733$di4.7072
> @newsfe14.ams2:
>
>> Hi,
>>
>> I need some help with something which is a little over my pay grade. :)
>>
>> The file which I must write has a header followed by a sequence of ints
>> each of which must be written as a 4 byte big-endian.
>>
>> The comp.lang.c has advice on finding out whether your machine is
>> little-endian or big-endian (little-endian in my case) but not on how
> to
>> do the kind of operation I need to do.
>>
>> I am sorry to say that I simply have no idea whatsoever how to write an
>> int to a file as a 4 byte big-endian. Can someone show me how please?
>>
>> Many thanks.
>>
> Hm... just reverse the routine below....
>
> int little_endian(char *c){
> 	static union{
> 		int k;
> 		char c[4];
> 	}p;
> 	p.c[0]=c[3];
> 	p.c[1]=c[2];
> 	p.c[2]=c[1];
> 	p.c[3]=c[0];
> 	return p.k;
> }

Works only on little-endian machines where sizeof(int) == 4.
Even though the OP states that his machine is little-endian, it seems
unlikely that he would want a solution which is this non-portable.
(And he didn't say whether his machine has 4-byte ints.)
-- 
Morris Keesan -- mkeesan@post.harvard.edu

[toc] | [prev] | [next] | [standalone]


#18468

From"Morris Keesan" <mkeesan@post.harvard.edu>
Date2012-03-10 14:57 -0500
Message-ID<op.way0ddbz5qv6o3@toshiba-laptop>
In reply to#18453
On Sat, 10 Mar 2012 13:00:50 -0500, MS <ms@no_spam_thanks.com> wrote:

> Hi,
>
> I need some help with something which is a little over my pay grade. :)
>
> The file which I must write has a header followed by a sequence of ints  
> each of which must be written as a 4 byte big-endian.
>
> The comp.lang.c has advice on finding out whether your machine is  
> little-endian or big-endian (little-endian in my case) but not on how to  
> do the kind of operation I need to do.
>
> I am sorry to say that I simply have no idea whatsoever how to write an  
> int to a file as a 4 byte big-endian. Can someone show me how please?

We'll assume that this means 4 8-bit bytes.

First, make sure that it will fit:
assert((sizeof(int) * CHAR_BIT) <= 32);
Then put the value into a (unsigned long int), so that you're guaranteed
to be working with an object which is at least 32 bits long, and you don't
have to worry about the implementation-defined results of applying
the >> operator to a signed quantity.
Then simply use bitwise operations (shifting and masking) to pick out
the successive octets of the low-order 32 bits of the int, starting from
the highest-order octet of those 32 bits.

unsigned long int ltemp = intvalue;
for (int i = 0; i < 3; ++i)
     fputc((intvalue >> (8 * (3 - i))) & 0xff, file);

Because you're working purely with the numerical value of the number,
this should work regardless of the endianness of the platform you're
doing this on.
-- 
Morris Keesan -- mkeesan@post.harvard.edu

[toc] | [prev] | [next] | [standalone]


#18479

FromIke Naar <ike@iceland.freeshell.org>
Date2012-03-10 21:17 +0000
Message-ID<slrn3vfsjlnh70.6cf.ike@iceland.freeshell.org>
In reply to#18468
On 2012-03-10, Morris Keesan <mkeesan@post.harvard.edu> wrote:
> unsigned long int ltemp = intvalue;
> for (int i = 0; i < 3; ++i)

s/3/4/ (assuming you want to output four bytes)

>      fputc((intvalue >> (8 * (3 - i))) & 0xff, file);

s/intvalue/ltemp/

[toc] | [prev] | [next] | [standalone]


#18490

From"Morris Keesan" <mkeesan@post.harvard.edu>
Date2012-03-10 17:22 -0500
Message-ID<op.way622et5qv6o3@toshiba-laptop>
In reply to#18479
On Sat, 10 Mar 2012 16:17:20 -0500, Ike Naar <ike@iceland.freeshell.org>  
wrote:

> On 2012-03-10, Morris Keesan <mkeesan@post.harvard.edu> wrote:
>> unsigned long int ltemp = intvalue;
>> for (int i = 0; i < 3; ++i)
>
> s/3/4/ (assuming you want to output four bytes)
>
>>      fputc((intvalue >> (8 * (3 - i))) & 0xff, file);
>
> s/intvalue/ltemp/

Oops.  Correct on both counts.  That's what I get for hitting "send"
without proofreading.
-- 
Morris Keesan -- mkeesan@post.harvard.edu

[toc] | [prev] | [next] | [standalone]


#18475

FromLew Pitcher <lpitcher@teksavvy.com>
Date2012-03-10 15:55 -0500
Message-ID<2dP6r.8481$7j4.8069@newsfe17.iad>
In reply to#18453
On Saturday 10 March 2012 13:00, in comp.lang.c, ms@no_spam_thanks.com
wrote:

> Hi,
> 
> I need some help with something which is a little over my pay grade. :)
> 
> The file which I must write has a header followed by a sequence of ints
> each of which must be written as a 4 byte big-endian.
> 
> The comp.lang.c has advice on finding out whether your machine is
> little-endian or big-endian (little-endian in my case) but not on how to
> do the kind of operation I need to do.
> 
> I am sorry to say that I simply have no idea whatsoever how to write an
> int to a file as a 4 byte big-endian. Can someone show me how please?

FWIW, I haven't yet read the other responses.

In my opinion, as a programmer, you shouldn't tackle this as a "how do I
determine the physical implementation of my environment, so that I can
perform a physical transformation".

Instead, you should address your problem as "how do I transform one logical
data structure into another?" 

You really don't care what format your source integer is in; it can be
big-endian or little-endian or middle-endian (or any of the other 21
byte-order combinations available for a 4-byte sequence). You have an
integer, that fits between INT_MIN and INT_MAX (or 0 and UINT_MAX) as a
source number.

You want to transform this into a sequence of 8-bit data items, ordered such
that the lowest addressed data item has the highest significance. You don't
want this sequence to exceed 32bits in length (4 8bit quantities).

Depending on whether your source integer is signed or unsigned, you can
simply iteratively modulo 256 the source to determine the lowest
significant octet, save that value, and then divide the source by 256 to
adjust. Do that 4 times for four octets, and abort if the remaining source
value is greater than 0 (signifying that the value can't fit in a 32bit
value).  Save the four modulo octets in the correct sequence for your
big-endian value.

On an implementation where CHAR_BIT == 8, this might look like


  #include <assert.h>
  #include <limits.h>

  unsigned int source_integer;
  unsigned char big_endian_target[4];
  int byte;

  assert(CHAR_BIT == 8);
  #define EIGHTBITS     (UCHAR_MAX + 1)


  for (byte = 3; byte > -1; byte--)
  {
    big_endian_target[byte] = source_integer % EIGHTBITS;
    source_integer = source_integer / EIGHTBITS;
  }
  assert(source_integer == 0);

-- 
Lew Pitcher

[toc] | [prev] | [next] | [standalone]


#18476

FromGeoff <geoff@invalid.invalid>
Date2012-03-10 13:01 -0800
Message-ID<g6gnl7d6uha7f01dmomc14k4i4smmleqrf@4ax.com>
In reply to#18453
On Sat, 10 Mar 2012 18:00:50 +0000, MS <ms@no_spam_thanks.com> wrote:

>Hi,
>
>I need some help with something which is a little over my pay grade. :)
>
>The file which I must write has a header followed by a sequence of ints 
>each of which must be written as a 4 byte big-endian.
>
>The comp.lang.c has advice on finding out whether your machine is 
>little-endian or big-endian (little-endian in my case) but not on how to 
>do the kind of operation I need to do.
>
>I am sorry to say that I simply have no idea whatsoever how to write an 
>int to a file as a 4 byte big-endian. Can someone show me how please?
>
>Many thanks.

What's wrong with using htonl()? Let your implementation worry about
the endianness of your platform. Use ntohl() to convert it when
reading the data back from the file.

[toc] | [prev] | [next] | [standalone]


#18515

FromStephen Sprunk <stephen@sprunk.org>
Date2012-03-10 22:01 -0600
Message-ID<jjh831$p8u$1@dont-email.me>
In reply to#18476
On 10-Mar-12 15:01, Geoff wrote:
> On Sat, 10 Mar 2012 18:00:50 +0000, MS <ms@no_spam_thanks.com> wrote:
>> I am sorry to say that I simply have no idea whatsoever how to write an 
>> int to a file as a 4 byte big-endian. Can someone show me how please?
> 
> What's wrong with using htonl()? Let your implementation worry about
> the endianness of your platform. Use ntohl() to convert it when
> reading the data back from the file.

htonl() et al are not part of Standard C; they usually come with a BSD
sockets library, which the OP may or may not have.

In any event, just giving him such functions would mean he misses out on
the opportunity to learn something very important, which he will likely
need to know when he later runs into file formats or network protocols
that, for historical reasons, require numbers to be in little-endian
order rather than the standard order.

S

-- 
Stephen Sprunk         "God does not play dice."  --Albert Einstein
CCIE #3723         "God is an inveterate gambler, and He throws the
K5SSS        dice at every possible opportunity." --Stephen Hawking

[toc] | [prev] | [next] | [standalone]


#18522

FromMalcolm McLean <malcolm.mclean5@btinternet.com>
Date2012-03-11 00:36 -0800
Message-ID<49a35d9c-a66a-4155-a703-189e8b6fd8b2@hs8g2000vbb.googlegroups.com>
In reply to#18515
On Mar 11, 4:01 am, Stephen Sprunk <step...@sprunk.org> wrote:
>
> In any event, just giving him such functions would mean he misses out on
> the opportunity to learn something very important, which he will likely
> need to know when he later runs into file formats or network protocols
> that, for historical reasons, require numbers to be in little-endian
> order rather than the standard order.
>
Yes, those little endians tried to take over the world, but they've
now been beaten back, and we can all open our integers at the big end
again.

[toc] | [prev] | [next] | [standalone]


#18664

From"io_x" <a@b.c.invalid>
Date2012-03-13 12:29 +0100
Message-ID<4f5f2e83$0$1383$4fafbaef@reader1.news.tin.it>
In reply to#18476
"Geoff" <geoff@invalid.invalid> ha scritto nel messaggio
news:g6gnl7d6uha7f01dmomc14k4i4smmleqrf@4ax.com...
> On Sat, 10 Mar 2012 18:00:50 +0000, MS <ms@no_spam_thanks.com> wrote:
>
>>Hi,
>>
>>I need some help with something which is a little over my pay grade. :)
>>
>>The file which I must write has a header followed by a sequence of ints
>>each of which must be written as a 4 byte big-endian.
>>
>>The comp.lang.c has advice on finding out whether your machine is
>>little-endian or big-endian (little-endian in my case) but not on how to
>>do the kind of operation I need to do.
>>
>>I am sorry to say that I simply have no idea whatsoever how to write an
>>int to a file as a 4 byte big-endian. Can someone show me how please?

what about, where u32 is unsigned 32 bit and u8 is unsigned 8 bit
u32  ValueToTraslateBytes=J;
u8                     v[4];

u[0]= (ValueToTraslateBytes>>24) &0xFF;
u[1]= (ValueToTraslateBytes>>16) &0xFF;
u[2]= (ValueToTraslateBytes>> 8) &0xFF;
u[3]=  ValueToTraslateBytes      &0xFF;

i don't remember if above is little of big endian... it is the way here
number are written in memory..  u32 7 is in hex bites are 0x07 0x00 0x00 0x00
or 07 00 00 00

>>Many thanks.
>
> What's wrong with using htonl()? Let your implementation worry about
> the endianness of your platform. Use ntohl() to convert it when
> reading the data back from the file.

i agree




[toc] | [prev] | [next] | [standalone]


#18669

From"io_x" <a@b.c.invalid>
Date2012-03-13 13:14 +0100
Message-ID<4f5f3926$0$1377$4fafbaef@reader2.news.tin.it>
In reply to#18664
"io_x" <a@b.c.invalid> ha scritto nel messaggio 
news:4f5f2e83$0$1383$4fafbaef@reader1.news.tin.it...
>
> "Geoff" <geoff@invalid.invalid> ha scritto nel messaggio
> news:g6gnl7d6uha7f01dmomc14k4i4smmleqrf@4ax.com...
>> On Sat, 10 Mar 2012 18:00:50 +0000, MS <ms@no_spam_thanks.com> wrote:
>>
>>>Hi,
>>>
>>>I need some help with something which is a little over my pay grade. :)
>>>
>>>The file which I must write has a header followed by a sequence of ints
>>>each of which must be written as a 4 byte big-endian.
>>>
>>>The comp.lang.c has advice on finding out whether your machine is
>>>little-endian or big-endian (little-endian in my case) but not on how to
>>>do the kind of operation I need to do.
>>>
>>>I am sorry to say that I simply have no idea whatsoever how to write an
>>>int to a file as a 4 byte big-endian. Can someone show me how please?
>
> what about, where u32 is unsigned 32 bit and u8 is unsigned 8 bit
> u32  ValueToTraslateBytes=J;
> u8                     v[4];
>
> u[0]= (ValueToTraslateBytes>>24) &0xFF;
> u[1]= (ValueToTraslateBytes>>16) &0xFF;
> u[2]= (ValueToTraslateBytes>> 8) &0xFF;
> u[3]=  ValueToTraslateBytes      &0xFF;

i realize here the correct way number appear here in memory should be:

 u[0]=  ValueToTraslateBytes      &0xFF;  // 7
 u[1]= (ValueToTraslateBytes>> 8) &0xFF;
 u[2]= (ValueToTraslateBytes>>16) &0xFF;
 u[3]= (ValueToTraslateBytes>>24) &0xFF;

> i don't remember if above is little of big endian... it is the way here
> number are written in memory..  u32 7 is in hex bites are 0x07 0x00 0x00 0x00
> or 07 00 00 00
>
>>>Many thanks.
>>
>> What's wrong with using htonl()? Let your implementation worry about
>> the endianness of your platform. Use ntohl() to convert it when
>> reading the data back from the file.
>
> i agree
>
>
>
>
> 

[toc] | [prev] | [next] | [standalone]


#18477

FromMalcolm McLean <malcolm.mclean5@btinternet.com>
Date2012-03-10 12:39 -0800
Message-ID<45a9bca1-6fa7-43fd-8aca-c1b280580e27@eb6g2000vbb.googlegroups.com>
In reply to#18453
On Mar 10, 6:00 pm, MS <ms@no_spam_thanks.com> wrote:
>
> I am sorry to say that I simply have no idea whatsoever how to write an
> int to a file as a 4 byte big-endian. Can someone show me how please?
>

/*
  write a 32 bit big endian integer to file
  Params: x - the integer
          fp - the open file
  Returns: 0 on success, error code on fail
*/
int fput32bigendian(long x, FILE *fp)
{
  fputc( (x >> 24) & 0xFF, fp);
  fputc( (x >> 16) & 0xFF, fp);
  fputc( (x >> 8) & 0xFF, fp);
  fputc( x & 0xFF, fp);
  return ferror(fp);
}

It doesn't matter whether the machine you are running on is big endian
or little endian. x is a long to avoid an annoying problem of right
shifts that are wider than the type not being defined properly. long
is guarateed at least 32 bits.
On some very esoteric architectures this function will not work
correctly, like one's compement machines. But you almost certainly
don't need to worry about them.

[toc] | [prev] | [next] | [standalone]


#18492

From"Morris Keesan" <mkeesan@post.harvard.edu>
Date2012-03-10 17:29 -0500
Message-ID<op.way7en185qv6o3@toshiba-laptop>
In reply to#18477
On Sat, 10 Mar 2012 15:39:41 -0500, Malcolm McLean  
<malcolm.mclean5@btinternet.com> wrote:

> /*
>   write a 32 bit big endian integer to file
>   Params: x - the integer
>           fp - the open file
>   Returns: 0 on success, error code on fail
> */
> int fput32bigendian(long x, FILE *fp)
> {
Not quite.  x should be unsigned long.  If x is negative, then
the results of the right shifts are implementation-defined, and
(perhaps surprisingly) there are no constraints on what the implementation
may define as the result.
>   fputc( (x >> 24) & 0xFF, fp);
>   fputc( (x >> 16) & 0xFF, fp);
>   fputc( (x >> 8) & 0xFF, fp);
>   fputc( x & 0xFF, fp);
>   return ferror(fp);
> }



-- 
Morris Keesan -- mkeesan@post.harvard.edu

[toc] | [prev] | [next] | [standalone]


#18495

FromMalcolm McLean <malcolm.mclean5@btinternet.com>
Date2012-03-10 15:02 -0800
Message-ID<edfdda46-831d-4781-8df4-7d4f4e27f323@hs8g2000vbb.googlegroups.com>
In reply to#18492
On Mar 10, 10:29 pm, "Morris Keesan" <mkee...@post.harvard.edu> wrote:
> On Sat, 10 Mar 2012 15:39:41 -0500, Malcolm McLean
>
> <malcolm.mcle...@btinternet.com> wrote:
> > /*
> >   write a 32 bit big endian integer to file
> >   Params: x - the integer
> >           fp - the open file
> >   Returns: 0 on success, error code on fail
> > */
> > int fput32bigendian(long x, FILE *fp)
> > {
>
> Not quite.  x should be unsigned long.  If x is negative, then
> the results of the right shifts are implementation-defined, and
> (perhaps surprisingly) there are no constraints on what the implementation
> may define as the result.
>
It might zero-pad or sign extend the long, but that's OK because we
ignore those bits. It wil break if it defines a right shift of a
negative number as some sort of runtime error, but it will also fail
on one's complement systems, or where the filing system uses 16-bit
binary bytes.

[toc] | [prev] | [next] | [standalone]


#18558

From"Morris Keesan" <mkeesan@post.harvard.edu>
Date2012-03-11 18:26 -0400
Message-ID<op.wa01yneq5qv6o3@toshiba-laptop>
In reply to#18495
On Sat, 10 Mar 2012 18:02:07 -0500, Malcolm McLean  
<malcolm.mclean5@btinternet.com> wrote:

> On Mar 10, 10:29 pm, "Morris Keesan" <mkee...@post.harvard.edu> wrote:
>> On Sat, 10 Mar 2012 15:39:41 -0500, Malcolm McLean
>>
>> <malcolm.mcle...@btinternet.com> wrote:
>> > /*
>> >   write a 32 bit big endian integer to file
>> >   Params: x - the integer
>> >           fp - the open file
>> >   Returns: 0 on success, error code on fail
>> > */
>> > int fput32bigendian(long x, FILE *fp)
>> > {
>>
>> Not quite.  x should be unsigned long.  If x is negative, then
>> the results of the right shifts are implementation-defined, and
>> (perhaps surprisingly) there are no constraints on what the  
>> implementation
>> may define as the result.
>>
> It might zero-pad or sign extend the long, but that's OK because we
> ignore those bits. It wil break if it defines a right shift of a
> negative number as some sort of runtime error, but it will also fail
> on one's complement systems, or where the filing system uses 16-bit
> binary bytes.

If zero-fill or sign-fill were the only allowed implementation-defined
results of right-shifting a negative quantity, that would be okay.
But there are no constraints on the values of any of the bits, even the
the bits that you might expect to be shifted.  The result of right-shifting
a negative number could be alternating 1 and 0 bits.  By declaring the
variable as unsigned, you avoid that uncertainty.
-- 
Morris Keesan -- mkeesan@post.harvard.edu

[toc] | [prev] | [next] | [standalone]


#18478

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2012-03-10 21:12 +0000
Message-ID<0.0928fc3ac240f0a0dbd7.20120310211244GMT.87zkbo9n3n.fsf@bsb.me.uk>
In reply to#18453
MS <ms@no_spam_thanks.com> writes:

> I need some help with something which is a little over my pay grade. :)
>
> The file which I must write has a header followed by a sequence of
> ints each of which must be written as a 4 byte big-endian.
>
> The comp.lang.c has advice on finding out whether your machine is
> little-endian or big-endian (little-endian in my case) but not on how
> to do the kind of operation I need to do.
>
> I am sorry to say that I simply have no idea whatsoever how to write
> an int to a file as a 4 byte big-endian. Can someone show me how
> please?

  void msb_write(unsigned int u, FILE *strm)
  {
       for (int i = sizeof u - 1; i >= 0; i--)
            fputc(u >> (CHAR_BIT * i), strm);
  }

CHAR_BIT is defined in limits.h, and you'll have to more the declaration
of i if your compiler does not accept this C99 syntax.

It may seem over the top to reference CHAR_BIT (rather than 8) and use
sizeof u (rather than 4) but I think it makes the code more "obviously"
correct.  Also, you can use the same loop code with other sizes of
integer type.

On machines that use odd representations of negative numbers, this won't
write the native bit pattern.  In fact it writes the 2's complement
representation because of way C defines the conversion from signed to
unsigned int.  This is probably what you want -- file formats that
specify the endianness of the header will almost certainly specify the
representation for negative numbers (if any are expected) and that will
almost certainly be 2's complement.

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


Page 2 of 3 — ← Prev page 1 [2] 3  Next page →

Back to top | Article view | comp.lang.c


csiph-web