Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #18453 > unrolled thread
| Started by | MS <ms@no_spam_thanks.com> |
|---|---|
| First post | 2012-03-10 18:00 +0000 |
| Last post | 2012-03-11 21:45 +0000 |
| Articles | 20 on this page of 46 — 23 participants |
Back to article view | Back to comp.lang.c
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 →
| From | Ike Naar <ike@sverige.freeshell.org> |
|---|---|
| Date | 2012-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]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2012-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]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2012-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]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2012-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]
| From | Sjouke Burry <s@b> |
|---|---|
| Date | 2012-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]
| From | "Morris Keesan" <mkeesan@post.harvard.edu> |
|---|---|
| Date | 2012-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]
| From | "Morris Keesan" <mkeesan@post.harvard.edu> |
|---|---|
| Date | 2012-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]
| From | Ike Naar <ike@iceland.freeshell.org> |
|---|---|
| Date | 2012-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]
| From | "Morris Keesan" <mkeesan@post.harvard.edu> |
|---|---|
| Date | 2012-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]
| From | Lew Pitcher <lpitcher@teksavvy.com> |
|---|---|
| Date | 2012-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]
| From | Geoff <geoff@invalid.invalid> |
|---|---|
| Date | 2012-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]
| From | Stephen Sprunk <stephen@sprunk.org> |
|---|---|
| Date | 2012-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]
| From | Malcolm McLean <malcolm.mclean5@btinternet.com> |
|---|---|
| Date | 2012-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]
| From | "io_x" <a@b.c.invalid> |
|---|---|
| Date | 2012-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]
| From | "io_x" <a@b.c.invalid> |
|---|---|
| Date | 2012-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]
| From | Malcolm McLean <malcolm.mclean5@btinternet.com> |
|---|---|
| Date | 2012-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]
| From | "Morris Keesan" <mkeesan@post.harvard.edu> |
|---|---|
| Date | 2012-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]
| From | Malcolm McLean <malcolm.mclean5@btinternet.com> |
|---|---|
| Date | 2012-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]
| From | "Morris Keesan" <mkeesan@post.harvard.edu> |
|---|---|
| Date | 2012-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]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2012-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