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
(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.
(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.
You close the input file, after reading only two bytes.
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