B
Ben Bacarisse
arnuld said:that was his plan but I did it with all tests inside the loop:
I think you are making this much more complex than it is -- and you are
not really doing what you think you are doing.
void compare_files( FILE* pf1, FILE* pf2 )
{
char line1[ARRSIZE];
char line2[ARRSIZE];
const char* *p1, *p2;
Eh? Does you compiler not complain about this later?
const char *begin_line1, *begin_line2;
What are these for?
int files_equal;
int file1, file2;
int eof_file1, eof_file2;
files_equal = 1;
file1 = file2 = 1;
eof_file1 = eof_file2 = 0;
You don't need five flags just to get this to work out!
while( files_equal && file1 && file2 )
{
begin_line1 = p1 = fgets( line1, ARRSIZE, pf1 );
begin_line2 = p2 = fgets( line2, ARRSIZE, pf2 );
if( !p1 && !p2 )
{
file1 = file2 = 0;
}
else if( (!p1 && p2) )
{
files_equal = 0;
eof_file1 = 1;
}
else if( !p2 && p1 )
{
files_equal = 0;
eof_file2 = 1;
}
else if( strcmp( p1, p2 ) )
{
files_equal = 0;
eof_file1 = eof_file2 = 1;
}
}
if( !files_equal )
{
if( eof_file1 )
{
puts(begin_line2);
}
else if( eof_file2 )
{
puts(begin_line1);
}
else if( eof_file1 && eof_file2 )
{
You can't ever get here. You've tied yourself in a logical knot.
puts( begin_line1 );
printf("\n-------------------------\n");
puts( begin_line2 );
}
}
}
int read_line(char *buf, size_t sz, FILE *fp) {
*buf = 0;
return fgets(buf, sz, fp) != NULL;
}
void compare_files(FILE *fp1, FILE *fp2) {
char l1[ARRSIZE], l2[ARRSIZE];
while (read_line(l1, sizeof l1, fp1) + read_line(l2, sizeof l2,
fp2)) {
if (strcmp(l1, l2)) {
fputs(l1, stdout);
puts("-------------------");
fputs(l2, stdout);
return;
}
}
}
}
The auxiliary function read_line is trivial, but it does exactly enough
to make the various tests (and subsequent output) trivial.
that is exactly what I was looking for and this is the 1st time I have
seen someone using + in a loop
I am quite surprised at both how a problem can be solved using 2
different approaches and that people think in very different ways when
they look at a problem.
I think it is a good problem. I am surprised that one of the
solutions on the clc wiki ignores differences in length. For what
it's worth, here is my full solution. I chose slightly different
names and the way main works is different.
/* K&R2, section 7.7, exercise 7.6 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define ARRSIZE 1000
int files_differ(FILE *, FILE *);
int main(int argc, char **argv)
{
int differ;
FILE *pf1, *pf2 = stdin;
if (argc < 2 || argc > 3) {
fprintf(stderr, "Give one or two file names as arguments.\n");
return EXIT_FAILURE;
}
if ((pf1 = fopen(argv[1], "r")) == NULL) {
fprintf(stderr, "Unable to open %s.\n", argv[1]);
return EXIT_FAILURE;
}
if (argc > 2 && (pf2 = fopen(argv[2], "r")) == NULL) {
fprintf(stderr, "Unable to open %s.\n", argv[2]);
fclose(pf1);
return EXIT_FAILURE;
}
differ = files_differ(pf1, pf2);
fclose(pf1);
fclose(pf2);
return differ ? EXIT_FAILURE : EXIT_SUCCESS;
}
int read_line(char *buf, size_t sz, FILE *fp)
{
*buf = 0;
return fgets(buf, sz, fp) != NULL;
}
int files_differ(FILE *fp1, FILE *fp2)
{
char l1[ARRSIZE], l2[ARRSIZE];
while (read_line(l1, sizeof l1, fp1) + read_line(l2, sizeof l2, fp2)) {
if (strcmp(l1, l2)) {
fputs(l1, stdout);
puts("-------------------");
fputs(l2, stdout);
return 1;
}
}
return 0;
}