code

  • Thread starter Bill Cunningham
  • Start date
B

Bill Cunningham

I worked and worked on this code until my compiler gave no more errors
even with -Wall -ansi turned on. So I think it's valid. The question is is
it doing what I want it to. I don't think so. Its never stopped and I've had
to interrupt it while running. I get a bunch of textual 00 all across the
screen. The idea is to take a binary and convert it to text and print it in
hex. I never get out of the do-while loop. Like a hex dump does but a hex
dump doesn't convert a binary into text. Is what I'm wanting valid? Am I
getting what I'm asking for. Here's the code if your reader lets you read it
neatly.

Bill
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
int buf[8200];
unsigned buf2[8200];
FILE *fp, *fp2;
if ((fp = fopen("6", "rb")) == NULL) {
perror("fopen 1");
exit(1);
}
if ((fp2 = fopen("b", "wt")) == NULL) {
perror("fopen 2");
exit(1);
}
do {
*buf = fscanf(fp, "%i", buf);
fprintf(fp2, "%i %x", *buf, *buf2);
}
while (*buf != EOF);
fclose(fp);
fclose(fp2);
printf(" %i %u", *buf, *buf2);
return 0;
}
 
B

Barry Schwarz

I worked and worked on this code until my compiler gave no more errors
even with -Wall -ansi turned on. So I think it's valid. The question is is

Think again.
it doing what I want it to. I don't think so. Its never stopped and I've had

See, upon reflection you can reach a correct conclusion.
to interrupt it while running. I get a bunch of textual 00 all across the
screen. The idea is to take a binary and convert it to text and print it in

Describe in detail what the input binary looks like.
hex. I never get out of the do-while loop. Like a hex dump does but a hex

If you want to print it in hex, what is the %i doing in your print
format?
dump doesn't convert a binary into text. Is what I'm wanting valid? Am I

Provide a short sample of input and what you want the output to look
like.
getting what I'm asking for. Here's the code if your reader lets you read it
neatly.

Bill
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
int buf[8200];
unsigned buf2[8200];

Where did these array sizes come from? What purpose did you want buf2
to serve?
FILE *fp, *fp2;
if ((fp = fopen("6", "rb")) == NULL) {
perror("fopen 1");
exit(1);
}
if ((fp2 = fopen("b", "wt")) == NULL) {
perror("fopen 2");
exit(1);
}
do {
*buf = fscanf(fp, "%i", buf);

This statement says
Read a bunch of text characters from a stream and convert them to
an int value. (I have no idea if the fact that you opened the file as
binary will have any effect on this operation.) Store the int value
in the int object pointed to by buf. (Since buf is an array, this
expression is converted to &buf[0] which is a perfectly good int*.)
After this completes, store the number of successful conversions in
*buf (which is the same as buf[0]. So you completely erase the value
that fscanf obtained and proceed to store either 0, 1, or EOF in
buf[0].

Under the very risky assumption that the call to fscanf had a real
purpose, I submit to you that this code does not accomplish what you
want. It is now up to you to tell us in PRECISE DETAIL what you
intended this statement to accomplish.

By the way, you should always check that fscanf succeeded.
fprintf(fp2, "%i %x", *buf, *buf2);

Since buf2 was never initialized with any values, all the elements of
the array are indeterminate. The act of evaluating indeterminate
values results in undefined behavior.

Since you don't specify any whitespace after the %x or before the %i,
whatever value is written for the %i for iteration n+1 will
immediately abut the value previously written for the %x on iteration
n. Something like
1 0x123456781 0x12345678...

It's a shame you have reneged on your commitment to indent your code.
while (*buf != EOF);
fclose(fp);
fclose(fp2);
printf(" %i %u", *buf, *buf2);

All of buf2 is still indeterminate so this is also undefined.
 
K

Keith Thompson

Bill Cunningham said:
The idea is to take a binary and convert it to text and print it in
hex. I never get out of the do-while loop. Like a hex dump does but a hex
dump doesn't convert a binary into text.

A hex dump *does* convert a binary into text. What did you think a hex
dump does?

[...]
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
int buf[8200];
unsigned buf2[8200];
FILE *fp, *fp2;
if ((fp = fopen("6", "rb")) == NULL) {
perror("fopen 1");
exit(1);
}

Your indentation is messed up. I suspect that you're indenting with
a mix of spaces and tabs, and the tabs are getting lost somewhere
between your news client and mine. Figure out how to indent with
spaces only, at least for code you post. (Filtering through the Unix
"expand" command is one way to do this.)

[...]
do {
*buf = fscanf(fp, "%i", buf);
fprintf(fp2, "%i %x", *buf, *buf2);
}
while (*buf != EOF);

For a do-while loop, it's clearer to put the while on the same line as
the "}"; otherwise it looks very much like a while loop.

[...]

There are numerous other problems with your code.

As you should realize by now, just getting a C program to compile
doesn't imply that it's going to work. There are other languages
where code that just compiles is more likely (though by no means
certain) to work correctly. (Python springs to mind.) Of course you've
been offered this advice before.
 
A

Angel

I worked and worked on this code until my compiler gave no more errors
even with -Wall -ansi turned on. So I think it's valid. The question is is
it doing what I want it to. I don't think so. Its never stopped and I've had
to interrupt it while running. I get a bunch of textual 00 all across the
screen. The idea is to take a binary and convert it to text and print it in
hex. I never get out of the do-while loop. Like a hex dump does but a hex
dump doesn't convert a binary into text. Is what I'm wanting valid? Am I
getting what I'm asking for. Here's the code if your reader lets you read it
neatly.

Here's a very short and simple program that reads a file and dumps the
contents as hexadecimal numbers. Error checking and reading the file
name from the command line instead of hard-coding it in are left as
exercises to the reader.

I think it is error-free and standard-compliant, but if not I'm sure
someone in the group will set me straight. ^^


#include <stdio.h>

#if !defined(BUFSIZ)
#define BUFSIZ ((size_t) 4096u)
#endif

int main(void)
{
FILE *file = fopen("/bin/ls", "rb");
unsigned char buf[BUFSIZ];
size_t nread;

while ((nread = fread(buf, sizeof(unsigned char), BUFSIZ, file)) > 0)
{
for (size_t foo = 0; foo < nread; foo++)
{
printf("%02x ", buf[foo]);
}
}
fclose(file);
}
 
B

Ben Bacarisse

Bill Cunningham said:
I worked and worked on this code until my compiler gave no more errors
even with -Wall -ansi turned on. So I think it's valid. The question is is
it doing what I want it to. I don't think so. Its never stopped and I've had
to interrupt it while running. I get a bunch of textual 00 all across the
screen. The idea is to take a binary and convert it to text and print it in
hex. I never get out of the do-while loop. Like a hex dump does but a hex
dump doesn't convert a binary into text. Is what I'm wanting valid? Am I
getting what I'm asking for. Here's the code if your reader lets you read it
neatly.

Bill
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
int buf[8200];
unsigned buf2[8200];
FILE *fp, *fp2;
if ((fp = fopen("6", "rb")) == NULL) {
perror("fopen 1");
exit(1);
}
if ((fp2 = fopen("b", "wt")) == NULL) {
perror("fopen 2");
exit(1);
}
do {
*buf = fscanf(fp, "%i", buf);
fprintf(fp2, "%i %x", *buf, *buf2);
}
while (*buf != EOF);
fclose(fp);
fclose(fp2);
printf(" %i %u", *buf, *buf2);
return 0;
}

There are four big things wrong here.

(1) The termination condition of the loop is wrong. It is always
better, when using scanf and friends, to loop while the function reports
success. Don't loop while it isn't something you don't want, loop while
it what you do want. In this case, fscanf will report 1 if it reads one
number so loop while the result is one.

(2) The place where you put the number read is the same place where you
store the success/failure result from fscanf. Even if the fscanf
succeeded in putting a number into the location pointed to by buf, that
number would be destroyed by putting a one into *buf (the same place).

(3) fscanf can't do what you want (well it can if you bend the rules but
that's not a good idea). Its purpose is to read textual data (e.g
sequences of digits in some text encoding like ASCII) and produce the
internal (binary) representation that your machine uses. That's exactly
the opposite of what you want to do.

(4) You print a piece of uninitialised data. *buf2 has never had
anything put into it so the output you will get is not based on the
input.

There are some other points: using 8200 element arrays when you use only
one element from each; writing "rt" in your second fopen call; printing
inside the loop even if the input fails; printing again outside the loop
and using a printf format such that you won't be able to interpret the
output, but those are all minor compared to the Big Four.
 
B

Bill Cunningham

Keith said:
Bill Cunningham said:
The idea is to take a binary and convert it to text and
print it in hex. I never get out of the do-while loop. Like a hex
dump does but a hex dump doesn't convert a binary into text.

A hex dump *does* convert a binary into text. What did you think a
hex dump does?

[...]
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
int buf[8200];
unsigned buf2[8200];
FILE *fp, *fp2;
if ((fp = fopen("6", "rb")) == NULL) {
perror("fopen 1");
exit(1);
}

Your indentation is messed up. I suspect that you're indenting with
a mix of spaces and tabs, and the tabs are getting lost somewhere
between your news client and mine. Figure out how to indent with
spaces only, at least for code you post. (Filtering through the Unix
"expand" command is one way to do this.)

[...]
do {
*buf = fscanf(fp, "%i", buf);
fprintf(fp2, "%i %x", *buf, *buf2);
}
while (*buf != EOF);

For a do-while loop, it's clearer to put the while on the same line as
the "}"; otherwise it looks very much like a while loop.

[...]

There are numerous other problems with your code.

As you should realize by now, just getting a C program to compile
doesn't imply that it's going to work. There are other languages
where code that just compiles is more likely (though by no means
certain) to work correctly. (Python springs to mind.) Of course
you've been offered this advice before.

My indentation seems to always mess up when writing to a newsreader.
When I write code I do use a tab. For about every line then run it through
indent. The result looks perfect. Then I run it through unix2dos to
straighten out the lines and post from OE using my XP. Somewhere in there
the indentation messes up. I was leary about using fscanf and fprintf anyway
here. The thought was the conversion ability to turn binary to text.

B
 
B

Bill Cunningham

Ben said:
There are four big things wrong here.

(1) The termination condition of the loop is wrong. It is always
better, when using scanf and friends, to loop while the function
reports success. Don't loop while it isn't something you don't want,
loop while it what you do want. In this case, fscanf will report 1
if it reads one number so loop while the result is one.

(2) The place where you put the number read is the same place where
you store the success/failure result from fscanf. Even if the fscanf
succeeded in putting a number into the location pointed to by buf,
that number would be destroyed by putting a one into *buf (the same
place).

(3) fscanf can't do what you want (well it can if you bend the rules
but that's not a good idea). Its purpose is to read textual data (e.g
sequences of digits in some text encoding like ASCII) and produce the
internal (binary) representation that your machine uses. That's
exactly the opposite of what you want to do.

I was leary as I said in another post about using fscanf and fprintf for
this. I was playing around with some code trying to learn something and
thought I'd post in order to learn something. Thanks for the advice. In
dealing with binary I'll stay away from fscanf and fprintf from now on. I
really don't know much about the *scanf family anyway.

Bill
 
B

Ben Bacarisse

Bill Cunningham said:
Ben Bacarisse wrote:

I was leary as I said in another post about using fscanf and fprintf for
this. I was playing around with some code trying to learn something and
thought I'd post in order to learn something. Thanks for the advice. In
dealing with binary I'll stay away from fscanf and fprintf from now on. I
really don't know much about the *scanf family anyway.

That's interesting. Why do will you stay away from fprintf when dealing
with binary data?

<snip>
 
B

Bill Cunningham

Ben said:
That's interesting. Why do will you stay away from fprintf when
dealing with binary data?

Not so much fprintf but fscanf. I really don't understand the formats and
such with fscanf or scanf. It was experimental for me picking them. I
dropped a line here at clc so I could find out what I did wrong as you say.
What I was hoping to do was covert the data. These two functions didn't work
the way I figured. Maybe if I understood the *scanfs better I would know how
and when to use them. Oh I've successfully used fprintf before.

Bill
 
B

Bill Cunningham

Ben said:
There are four big things wrong here.

(1) The termination condition of the loop is wrong. It is always
better, when using scanf and friends, to loop while the function
reports success. Don't loop while it isn't something you don't want,
loop while it what you do want. In this case, fscanf will report 1
if it reads one number so loop while the result is one.

Didn't know that. ok. Does it only return 0 or 1? Or the number of bytes
read like fread? That's what I'm trying to treat this like.
(2) The place where you put the number read is the same place where
you store the success/failure result from fscanf. Even if the fscanf
succeeded in putting a number into the location pointed to by buf,
that number would be destroyed by putting a one into *buf (the same
place).

I have misused fscanf because I don't understand the *scanfs. I thought
it would return like fread. Bytes.
(3) fscanf can't do what you want (well it can if you bend the rules
but that's not a good idea). Its purpose is to read textual data (e.g
sequences of digits in some text encoding like ASCII) and produce the
internal (binary) representation that your machine uses. That's
exactly the opposite of what you want to do.
Understood.

(4) You print a piece of uninitialised data. *buf2 has never had
anything put into it so the output you will get is not based on the
input.
ok.

There are some other points: using 8200 element arrays when you use
only one element from each; writing "rt" in your second fopen call;
printing inside the loop even if the input fails; printing again
outside the loop and using a printf format such that you won't be
able to interpret the output, but those are all minor compared to the
Big Four.

ok
 
K

Keith Thompson

Bill Cunningham said:
Didn't know that. ok. Does it only return 0 or 1? Or the number of bytes
read like fread? That's what I'm trying to treat this like.

You'll find the answer to that question in the documentation for
fscanf. Read it.

[...]
I have misused fscanf because I don't understand the *scanfs. I thought
it would return like fread. Bytes.

Why would you think that? Why would you write a call to fscanf without
reading the documentation, which clearly tells you what it returns?

As I've advised you multiple times before, you should *never* write
a call to a C function without first reading and understanding the
documentation for that function.

[...]
 
B

Bill Cunningham

Keith said:
Bill Cunningham said:
Didn't know that. ok. Does it only return 0 or 1? Or the number
of bytes read like fread? That's what I'm trying to treat this like.

You'll find the answer to that question in the documentation for
fscanf. Read it.

[...]
I have misused fscanf because I don't understand the *scanfs. I
thought it would return like fread. Bytes.

Why would you think that? Why would you write a call to fscanf
without reading the documentation, which clearly tells you what it
returns?

As I've advised you multiple times before, you should *never* write
a call to a C function without first reading and understanding the
documentation for that function.

[...]

I did read the man pages but evedently didn't understand them. The man
page said fscanf returns EOF thus it is in my code. EOF on error and end of
file the way I understand it.

Bill
 
B

Bill Cunningham

Keith said:
Bill Cunningham said:
Didn't know that. ok. Does it only return 0 or 1? Or the number
of bytes read like fread? That's what I'm trying to treat this like.

You'll find the answer to that question in the documentation for
fscanf. Read it.

[...]
I have misused fscanf because I don't understand the *scanfs. I
thought it would return like fread. Bytes.

Why would you think that? Why would you write a call to fscanf
without reading the documentation, which clearly tells you what it
returns?

As I've advised you multiple times before, you should *never* write
a call to a C function without first reading and understanding the
documentation for that function.

[...]
RETURN VALUES
These functions return the number of input items assigned. This can be
fewer than provided for, or even zero, in the event of a matching fail-
ure. Zero indicates that, although there was input available, no
conver-
sions were assigned; typically this is due to an invalid input
character,
such as an alphabetic character for a `%d' conversion. The value EOF
is
returned if an input failure occurs before any conversion such as an
end-
of-file occurs. If an error or end-of-file occurs after conversion has
begun, the number of conversions which were successfully completed is
returned.
I don't see anything in here about 0 of 1 but I do see that EOF is
mentioned.Bill
 
K

Keith Thompson

Bill Cunningham said:
I did read the man pages but evedently didn't understand them. The man
page said fscanf returns EOF thus it is in my code. EOF on error and end of
file the way I understand it.

Ok, fair enough.

But in the successful case, it returns the number of input items
assigned. For example, if you tell it to read 2 items, and it's only
able to read 1 item, then it will return 1, not EOF.

You should read and understand the documentation before *either* writing
a call to a function *or* speculating here what the function does.

Upthread, you wrote:

| Didn't know that. ok. Does it only return 0 or 1? Or the number of
| bytes read like fread? That's what I'm trying to treat this like.

That was pure guesswork that could have been avoided if you'd read
the man page.
 
B

Bill Cunningham

Bill said:
I don't see anything in here about 0 of 1 but I do see that EOF is
mentioned.Bill

I mean 1 not zero. I guess zero would be no input.

int c;
c=fscanf...
while(c!=0)...loop

Would that be a correct statement for this or maybe,
while(c!=0||c!=EOF){}

B
 
O

osmium

Bill Cunningham said:
Keith said:
Bill Cunningham said:
Ben Bacarisse wrote:
There are four big things wrong here.

(1) The termination condition of the loop is wrong. It is always
better, when using scanf and friends, to loop while the function
reports success. Don't loop while it isn't something you don't
want, loop while it what you do want. In this case, fscanf will
report 1 if it reads one number so loop while the result is one.

Didn't know that. ok. Does it only return 0 or 1? Or the number
of bytes read like fread? That's what I'm trying to treat this like.

You'll find the answer to that question in the documentation for
fscanf. Read it.

[...]
I have misused fscanf because I don't understand the *scanfs. I
thought it would return like fread. Bytes.

Why would you think that? Why would you write a call to fscanf
without reading the documentation, which clearly tells you what it
returns?

As I've advised you multiple times before, you should *never* write
a call to a C function without first reading and understanding the
documentation for that function.

[...]

I did read the man pages but evedently didn't understand them. The man
page said fscanf returns EOF thus it is in my code. EOF on error and end
of file the way I understand it.

Your man page doesn't say that, now does it?

Type in *exactly* what K&R say, no digressions or observations or thoughts
or feelings by you, and we will help you read it word by word.
 
B

Ben Bacarisse

Keith Thompson said:
Ok, fair enough.

But in the successful case, it returns the number of input items
assigned. For example, if you tell it to read 2 items, and it's only
able to read 1 item, then it will return 1, not EOF.

More the point (at least more applicable to this case) it returns 0 if
there is data (i.e. no EOF yet) but it can't match the kind of data you
want -- a so-called matching failure. That's what was happening here.


<snip>
 
B

Barry Schwarz

I mean 1 not zero. I guess zero would be no input.

int c;
c=fscanf...
while(c!=0)...loop

If c is not 0, did you get the items you asked for? In other word, is
there a situation where c is not 0 but you did not get what you asked
for?

How is c ever going to change?
Would that be a correct statement for this or maybe,
while(c!=0||c!=EOF){}

Under what possible conditions could this ever evaluate to false?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

error 28
write error 13
URGENT 1
Working with files 1
code snippet 92
code 50
strtok 7
fseek 17

Members online

Forum statistics

Threads
473,733
Messages
2,569,439
Members
44,829
Latest member
PIXThurman

Latest Threads

Top