neater code

B

Bill Cunningham

I wrote this small program to take an ELF format file and turn it inside
out. Turn all off bits on and vice versa. I think this code can be a little
neater and I found that a 2Kb file became 2 bytes. I don't know if the
system is reading the file data wrong because everything has been "flipped"
or what. I want to be able to flip everything back but I might have in doing
this lost data. Could this file be made to look a little neater with maybe a
while or two instead of the IF's ? I tried it and failed. Any suggestions?

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

int main(int argc, char **argv)
{
FILE *fp, *fp0;
int o = 0;
int i = 0;
int fl = ~o;
if (argc != 3) {
fputs("flip usage error\n", stderr);
exit(1);
}
fp = fopen(argv[1], "rb");
fp0 = fopen(argv[2], "wb");
if ((i = getc(fp)) != EOF)
i = getc(fp);
if ((o = putc(fl, fp0)) != EOF)
o = putc(fl, fp0);

fclose(fp);
fclose(fp0);
exit(0);
}
 
C

Chad

    I wrote this small program to take an ELF format file and turn it inside
out. Turn all off bits on and vice versa. I think this code can be a little
neater and I found that a 2Kb file became 2 bytes. I don't know if the
system is reading the file data wrong because everything has been "flipped"
or what. I want to be able to flip everything back but I might have in doing
this lost data. Could this file be made to look a little neater with maybe a
while or two instead of the IF's ? I tried it and failed. Any suggestions?

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

int main(int argc, char **argv)
{
    FILE *fp, *fp0;
    int o = 0;
    int i = 0;
    int fl = ~o;
    if (argc != 3) {
        fputs("flip usage error\n", stderr);
        exit(1);
    }
    fp = fopen(argv[1], "rb");
    fp0 = fopen(argv[2], "wb");
    if ((i = getc(fp)) != EOF)
        i = getc(fp);
    if ((o = putc(fl, fp0)) != EOF)
        o = putc(fl, fp0);

    fclose(fp);
    fclose(fp0);
    exit(0);



}

ELF? You mean the men that wear green tights and help Santa Claus?
 
L

Lew Pitcher

I wrote this small program to take an ELF format file and turn it
inside out.

Actually, ELF format has nothing to do with it. Your program doesn't depend
on an ELF input at all.
Turn all off bits on and vice versa.

If that was the intent, then you didn't think it through very well. You see,
that's /not/ what your program does, not even close.
I think this code can be a little neater

Likely ;-) /All/ programs look untidy
and I found that a 2Kb file became 2 bytes.

Understandable, given your program.
I don't know if the system is reading the file data wrong because
everything has been "flipped" or what.

No. You just wrote a 2 byte file. That's what your logic explicitly does. It
does not "flip bits" or transform an input file
I want to be able to flip everything back but I might have in doing this
lost data.

So long as you kept the original input file, you should be OK. If you ran
your program with input and output files being the same file, then you
killed yourself. The input file cannot be recovered from the output file.
Could this file be made to look a little neater with maybe a while or two
instead of the IF's ?

Very certainly
I tried it and failed. Any suggestions?

Let's look at your code, shall we?
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv)
{
FILE *fp, *fp0;
int o = 0;
int i = 0;
int fl = ~o;

Since /o/ is already set to 0, then /fl/ is now set to ~0, or "all bits 1"

if (argc != 3) {
fputs("flip usage error\n", stderr);
exit(1);
}

OK. Adequate argument checking for a sample program.

fp = fopen(argv[1], "rb");

What if the file named by argv[1] doesn't exist? Will fopen() return a
valid FILE*? What should your program do if the input file doesn't exist?
Should it continue, create the output file, and attempt to process it's
non-existant input?

fp0 = fopen(argv[2], "wb");

What if the file named by argv[2] is the same as the file named by argv[1]?
A "w" mode will cause fopen() to truncate the named file, and that'll
delete any data in it. If argv[2] names the same file as argv[1], then
you've just killed all your input. What other situations might you want to
cover here? What if fopen() returns an error?

if ((i = getc(fp)) != EOF)

You read a character from the input file,
save it in /i/,
test it to see if it equals the EOF indicator, and
execute the next line if it doesn't.

That's one byte read out of your input file

i = getc(fp);

(If the first input byte was not EOF),
you read a (second) character from the input and save it in /i/, discarding
the first input byte.

That's now two bytes read from the input file.

if ((o = putc(fl, fp0)) != EOF)
You write one byte of ~0 fron /fl/ to the output file,
save the results of the write (which can be either your original ~0 or
EOF) in /o/,
test the results to see if it equals the EOF indicator, and
execute the next line if the results were not EOF

That's one byte of ~0 written to your output file.

o = putc(fl, fp0);
(If the first write succeeded)
you write a second byte of ~0 from /fl/ to the output file, saving the
results of the putc() in /o/ (discarding the previous value of /o/)

That's now two bytes written to the output file.

fclose(fp);

You close the input file, after reading only two bytes.

fclose(fp0);

You close the output file, after writing only two bytes.


You terminate the execution of your program, with a returncode of 0


Notice in the above analysis...

1) You don't read the entire input file. You only read two bytes from the
input.

2) You don't write any of the input (transformed or not) to the output file.
You write only two bytes (at most) of constant data, unrelated to the
contents of the input file.

3) You don't do any transformation on the data obtained from the input file.

4) You don't prevent your program from deleting all the contents of the
input file before processing it

--------------------------------------------------------------

For processing /all/ the input, you need a looping mechanism.

The body of the loop should perform your "complement" transformation on the
input byte, and then write the byte to the output. The loop control itself
should obtain the next input byte, and terminate when the input is EOF.

You want something like ...

while ((i = getc(fp)) != EOF) /* get a byte into /i/, stop on EOF */
{
fl = ~i; /* /fl/ is bitflipped /i/ */
if ((o = putc(fl, fp0)) == EOF) /* write /fl/ to output file */
{ /* if write returned EOF */
fputs("flip failed to write", stderr); /* then we have an error */
exit(2);
}
}

HTH
 
A

Andrea Laforgia

I agree that he should report all the errors; don't you think that
something like the following would be more readable?

void closeFile(FILE *fp) {
if (fclose(fp)!=0) {
reportTheError(...);
}
}

void exitWithError(...) {
...
exit(1);
}

void reportTheError(...) {
...
}

int main(int argc, char **argv) {

FILE *fpi, *fpo;
unsigned char c;

if (argc != 3)
exitWithError(...);

if (!(fpi = fopen(argv[1], "rb"))
exitWithError(...);

if (!(fpo = fopen(argv[2], "wb")) {
closeFile(fpi);
exitWithError(...);
}

while (fread(&c, 1, 1, fpi)==1) {
unsigned char not_c = ~c;
if (fwrite(&not_c, 1, 1, fpo)!=1) {
reportTheError(...);
break;
}
}

if (ferror(fpi)) {
reportTheError(...);
}

closeFile(fpo);
closeFile(fpi);

return 0;
}
 
K

Keith Thompson

Bill Cunningham said:
I wrote this small program to take an ELF format file and turn it inside
out. Turn all off bits on and vice versa. I think this code can be a little
neater and I found that a 2Kb file became 2 bytes. I don't know if the
system is reading the file data wrong because everything has been "flipped"
or what. I want to be able to flip everything back but I might have in doing
this lost data. Could this file be made to look a little neater with maybe a
while or two instead of the IF's ? I tried it and failed. Any suggestions?

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

int main(int argc, char **argv)
{
FILE *fp, *fp0;
int o = 0;
int i = 0;
int fl = ~o;
if (argc != 3) {
fputs("flip usage error\n", stderr);
exit(1);
}
fp = fopen(argv[1], "rb");
fp0 = fopen(argv[2], "wb");
if ((i = getc(fp)) != EOF)
i = getc(fp);
if ((o = putc(fl, fp0)) != EOF)
o = putc(fl, fp0);

fclose(fp);
fclose(fp0);
exit(0);
}

The real problem is that you think the problem with your code is
neatness rather than correctness.

A while loop is not "neater" than an if statement; it's a different
statement that does a very different thing. You don't choose to
use one or the other based on esthetics; you choose based on which
one does the job you want to do.

Your problem description is "to take an ELF format file and turn
it inside out. Turn all off bits on and vice versa."

What does the format of the input file (ELF or otherwise) have to
do with with this? ELF is an object file format. Inverting all
the bits in an ELF file gives you garbage.

Assuming you change "an ELF format file" to "a file", you're
left with something that might be a reasonable problem statement.
There might even be good reasons to generate a bit-flipped copy of
a given file; it might be a quick and dirty way to render a file
unusable while letting it be easily restored by inverting it again.
And as a simple programming exercise, it's not bad.

The big problem is that the program you posted doesn't do anything
resembling what you described.

The only value you ever write to the output file is fl. The value
of fl never changes after it's been initialized, and you only write
it (at most) twice.

There must have been a long chain of misconceptions leading
to the code you posted. One link in that chain was probably
a misunderstanding of the difference between "if" and "while".
Another *might* have been an assumption that, once you initialize
fl to ~o, it will remain equal to ~o as the value of o changes,
but that's only a guess on my part.

You're doing the equivalent of asking a driving instructor whether
you're using your turn signals properly, when the real problem is
that you need to stop driving the wrong way on the sidewalk.
 
M

Michael Foukarakis

    I wrote this small program to take an ELF format file and turn it inside
out. Turn all off bits on and vice versa. I think this code can be a little
neater and I found that a 2Kb file became 2 bytes. I don't know if the
system is reading the file data wrong because everything has been "flipped"
or what. I want to be able to flip everything back but I might have in doing
this lost data. Could this file be made to look a little neater with maybe a
while or two instead of the IF's ? I tried it and failed. Any suggestions?

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

int main(int argc, char **argv)
{
    FILE *fp, *fp0;
    int o = 0;
    int i = 0;
    int fl = ~o;
    if (argc != 3) {
        fputs("flip usage error\n", stderr);
        exit(1);
    }
    fp = fopen(argv[1], "rb");
    fp0 = fopen(argv[2], "wb");
    if ((i = getc(fp)) != EOF)
        i = getc(fp);
    if ((o = putc(fl, fp0)) != EOF)
        o = putc(fl, fp0);

    fclose(fp);
    fclose(fp0);
    exit(0);

}
I tried rewriting your program in a neater way, here's what I came up
with:

#include <stdio.h> /* Skip unnecessary includes for brevity */

int main(int argc, char **argv) /* to hell with the brevity */
{
while(printf("Hello world!\n") < 0)
printf("Error greeting world, please advise!\n");
return(~0); /* Flipping bits since ANSI C */
}

You can clearly see the part where the bits are reversed, the program
also prints a greeting for general awesomeness.
 
B

Barry Schwarz

I agree that he should report all the errors; don't you think that
something like the following would be more readable?

void closeFile(FILE *fp) {
if (fclose(fp)!=0) {
reportTheError(...);

How does reportTheError tell the difference between the input file and
the output file? How does closeFile inform the calling function that
an error occurred.?
}
}

void exitWithError(...) {
...
exit(1);

Why not use a portable return value?
}

void reportTheError(...) {
...
}

int main(int argc, char **argv) {

FILE *fpi, *fpo;
unsigned char c;

if (argc != 3)
exitWithError(...);

if (!(fpi = fopen(argv[1], "rb"))
exitWithError(...);

if (!(fpo = fopen(argv[2], "wb")) {
closeFile(fpi);
exitWithError(...);
}

while (fread(&c, 1, 1, fpi)==1) {
unsigned char not_c = ~c;
if (fwrite(&not_c, 1, 1, fpo)!=1) {
reportTheError(...);
break;
}
}

if (ferror(fpi)) {
reportTheError(...);
}

closeFile(fpo);
closeFile(fpi);

return 0;
}
 
B

Bill Cunningham

I tried rewriting your program in a neater way, here's what I came up
with:

#include <stdio.h> /* Skip unnecessary includes for brevity */

int main(int argc, char **argv) /* to hell with the brevity */
{
while(printf("Hello world!\n") < 0)
printf("Error greeting world, please advise!\n");
return(~0); /* Flipping bits since ANSI C */
}

You can clearly see the part where the bits are reversed, the program
also prints a greeting for general awesomeness.

Geesh that's much shorter. A simple return is all that's needed?

Bill
 
S

santosh

Bill said:
I tried rewriting your program in a neater way, here's what I came up
with:

#include <stdio.h> /* Skip unnecessary includes for brevity */

int main(int argc, char **argv) /* to hell with the brevity */
{
while(printf("Hello world!\n") < 0)
printf("Error greeting world, please advise!\n");
return(~0); /* Flipping bits since ANSI C */
}

You can clearly see the part where the bits are reversed, the program
also prints a greeting for general awesomeness.

Geesh that's much shorter. A simple return is all that's needed?

No. See Richard's post.
 
K

Keith Thompson

Bill Cunningham said:
news:1ec6bcad-d0b1-4938-8982-08f7820054cf@l11g2000yqb.googlegroups.com... [...]
return(~0); /* Flipping bits since ANSI C */
}

You can clearly see the part where the bits are reversed, the program
also prints a greeting for general awesomeness.

Geesh that's much shorter. A simple return is all that's needed?

It depends on what you're trying to do. For what you originally
claimed you were trying to do, it's laughably insufficient.
 
A

Andrea Laforgia

How does reportTheError tell the difference between the input file and
the output file?

Correct. I guess closeFile() is not a very good idea :)
How does closeFile inform the calling function that
an error occurred.?

Well, I didn't think it should. I thought of it as a replacement of
the group of lines attempting to close the file and reporting the
error. Instead of repeating those lines, one could use closeFile(),
but I realize that one should also pass a good bunch of information
together with the file pointer, in order to have a reliable error log,
which might make this function very little worth using :)
Why not use a portable return value?

Right: EXIT_FAILURE. I simply copied the initial approach.
 
M

Michael Foukarakis

Bill Cunningham said:
news:1ec6bcad-d0b1-4938-8982-08f7820054cf@l11g2000yqb.googlegroups.com.... [...]
    return(~0); /* Flipping bits since ANSI C */
}
You can clearly see the part where the bits are reversed, the program
also prints a greeting for general awesomeness.
    Geesh that's much shorter. A simple return is all that's needed?

It depends on what you're trying to do.  For what you originally
claimed you were trying to do, it's laughably insufficient.

But I wasn't trying to do that, I was simply going for a neater
version of its code. It turned out that lots of functionality could be
stripped leading to a much neater, visually speaking, program.
 
N

Nick Keighley

I agree that he should report all the errors; don't you think that
something like the following would be more readable?

I doubt it! Richard heathfield is a structured programmer of the old
school.

"programs shall be written using only the constructs sequence,
iteration and conditional"
"each code block and function shall have a single entry point and a
single exit point"

no gotos no early exits

void closeFile(FILE *fp) {
   if (fclose(fp)!=0) {
      reportTheError(...);
   }

}

void exitWithError(...) {
     ...
     exit(1);

good grief. You are suggesting Richard should invoke implementaion
defined behaviour when there is a well defined portable solution?!

:)

}

void reportTheError(...) {
     ...

}

int main(int argc, char **argv) {

    FILE *fpi, *fpo;
    unsigned char c;

    if (argc != 3)
      exitWithError(...);

    if (!(fpi = fopen(argv[1], "rb"))
      exitWithError(...);

    if (!(fpo = fopen(argv[2], "wb")) {
      closeFile(fpi);
      exitWithError(...);
    }

    while (fread(&c, 1, 1, fpi)==1) {
       unsigned char not_c = ~c;        
       if (fwrite(&not_c, 1, 1, fpo)!=1) {
          reportTheError(...);          
          break;
       }
    }

    if (ferror(fpi)) {
       reportTheError(...);
    }

    closeFile(fpo);
    closeFile(fpi);

    return 0;



}
 
J

_JusSx_

I wrote this small program to take an ELF format file and turn it inside
out. Turn all off bits on and vice versa. I think this code can be a little
neater and I found that a 2Kb file became 2 bytes. I don't know if the
system is reading the file data wrong because everything has been "flipped"
or what. I want to be able to flip everything back but I might have in doing
this lost data. Could this file be made to look a little neater with maybe a
while or two instead of the IF's ? I tried it and failed. Any suggestions?

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

int main(int argc, char **argv)
{
FILE *fp, *fp0;
int o = 0;
int i = 0;
int fl = ~o;
if (argc != 3) {
fputs("flip usage error\n", stderr);
exit(1);
}
fp = fopen(argv[1], "rb");
fp0 = fopen(argv[2], "wb");
if ((i = getc(fp)) != EOF)
i = getc(fp);
if ((o = putc(fl, fp0)) != EOF)
o = putc(fl, fp0);

fclose(fp);
fclose(fp0);
exit(0);
}

#v+
#include <stdio.h>
#include <stdlib.h>


int
main (argc, argv)
int argc;
char *argv[];
{
int c;

while ((c = fgetc(stdin)) != EOF)
fputc(~c, stdout);

return EXIT_SUCCESS;
}
#v-

do you like this way?

-jussx-
 
I

Ian Collins

_JusSx_ said:
#v+
Eh?
#include <stdio.h>
#include <stdlib.h>


int
main (argc, argv)
int argc;
char *argv[];

Yuck, that's ancient K&R style. Avoid at all costs!
 

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

getc fgetc 7
How can I view / open / render / display a pdf file with c code? 0
code 34
URGENT 1
comparison error 12
code 50
Program not giving any output 33
Command Line Arguments 0

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top