mersenneforum.org  

Go Back   mersenneforum.org > Other Stuff > Archived Projects > NFSNET Discussion

 
 
Thread Tools
Old 2005-07-12, 03:41   #12
Wacky
 
Wacky's Avatar
 
Jun 2003
The Texas Hill Country

100010000012 Posts
Default

Quote:
Originally Posted by cjohnsto
How about the following ANSI C code for comparisons.
If this isn't what you wanted tell me why and what you do want.
Thanks for the code. There is only a small change that is needed to allow it the option to take one of its inputs from stdin. I'll start using it tomorrow.
Wacky is offline  
Old 2005-07-13, 20:56   #13
gribozavr
 
gribozavr's Avatar
 
Mar 2005
Internet; Ukraine, Kiev

11×37 Posts
Default

Quote:
Originally Posted by Wacky
Thanks for the code. There is only a small change that is needed to allow it the option to take one of its inputs from stdin. I'll start using it tomorrow.
This code has a bug in it. It prints parts of wrong lines, though line numbers are OK. For example:
cmp.1:
Code:
foobar
ignored XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX qqq
short line
cmp.2:
Code:
foobar
ignored
long line XXXXXXXXXXXXXX
cmp.skip:
Code:
2
Compare them:
Code:
$ ./cmp cmp.1 cmp.2 cmp.skip
Difference on line 3
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX qqq

long line XXXXXXXXXXXXXX
While we expected:
Code:
$ ./cmp.fixed cmp.1 cmp.2 cmp.skip
difference on line 3
short line

long line XXXXXXXXXXXXXX

I have fixed it. Other changes include:
* "magic numbers" are turned into preprocessor macros
* binary mode for files (you never know where it will be running)
* use perror() for reporting I/O errors
* use strcmp() for comparing strings
* use strchr() for looking for newline

By the way, just ask me and I will compile it with MinGW for Windows, if you ever need it; executable will be less than 10 KB in size.

Here it is:
Code:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#define BUFFER_SIZE 1024

#define STATUS_FILES_IDENTICAL     0
#define STATUS_FILES_DIFFER       -1
#define STATUS_INVALID_PARAMETERS  1
#define STATUS_FILE_OPEN_ERROR     2
#define STATUS_FILE_READ_ERROR     3

int main(int argc, char *argv[])
{
        FILE *skipfile = NULL, *in1 = NULL, *in2 = NULL;
        int   skip = -1;
        char  line1[BUFFER_SIZE], line2[BUFFER_SIZE];
        char *res1 = NULL, *res2 = NULL;
        int   lineno = 0;
        int   skipped = 1; /* was previous line skipped? when do we need to read nest line from skipfile */
        int   eol = 0;

        if ((argc < 3) || (argc > 4))
        {
                fprintf(stderr,
"usage: %s file1 file2 [skipfile]\n"
"skipfile contains line numbers on seperate lines that will not be compared\n"
"between file1 and file2 this file must be sorted\n",
                        argv[0]);
                return STATUS_INVALID_PARAMETERS;
        }
        if (argc == 4)
        {
                skipfile = fopen(argv[3], "rb");
                if (!skipfile)
                {
                        perror(argv[3]);
                        return STATUS_FILE_OPEN_ERROR;
                }
        }

        in1 = fopen(argv[1], "rb");
        in2 = fopen(argv[2], "rb");
        if (!in1)
        {
                perror(argv[1]);
                return STATUS_FILE_OPEN_ERROR;
        }
        if (!in2)
        {
                perror(argv[2]);
                return STATUS_FILE_OPEN_ERROR;
        }

        while(1)
        {
                lineno++;
                if (skipfile && skipped)
                {
                        res1 = fgets(line1, BUFFER_SIZE, skipfile);
                        if(!res1 && !feof(skipfile))
                        {
                                perror(argv[3]);
                                return STATUS_FILE_READ_ERROR;
                        }
                        if(res1)
                        {
                                skip = atoi(line1);
                                skipped = 0;
                        }
                }
                eol = 0;
                while (!eol)
                {
                        res1 = fgets(line1, BUFFER_SIZE, in1);
                        if(!res1 && !feof(in1))
                        {
                                perror(argv[1]);
                                return STATUS_FILE_READ_ERROR;
                        }
                        res2 = fgets(line2, BUFFER_SIZE, in2);
                        if(!res2 && !feof(in2))
                        {
                                perror(argv[2]);
                                return STATUS_FILE_READ_ERROR;
                        }
                        if (!res1 || !res2)
                        {
                                if (feof(in1) && feof(in2))
                                {
                                        fprintf(stderr, "files are identical\n");
                                        return STATUS_FILES_IDENTICAL;
                                }
                                else
                                {
                                        fprintf(stderr, "files differ in length\n");
                                        if (feof(in1))
                                        {
                                                printf("%s is shorter\n", argv[1]);
                                        }
                                        if (feof(in2))
                                        {
                                                printf("%s is shorter\n", argv[2]);
                                        }
                                        return -1;
                                }
                        }
                        if(lineno == skip)
                        {
                                while(!strchr(line1, '\n') && res1 && !feof(in1))
                                {
                                        res1 = fgets(line1, BUFFER_SIZE, in1);
                                }
                                if(!res1 && !feof(in1))
                                {
                                        perror(argv[1]);
                                        return STATUS_FILE_READ_ERROR;
                                }
                                while(!strchr(line2, '\n') && res2 && !feof(in2))
                                {
                                        res1 = fgets(line2, BUFFER_SIZE, in2);
                                }
                                if(!res2 && !feof(in2))
                                {
                                        perror(argv[2]);
                                        return STATUS_FILE_READ_ERROR;
                                }
                                eol = 1;
                                skipped = 1;
                                continue;
                        }

                        if(strncmp(line1, line2, BUFFER_SIZE) != 0)
                        {
                                fprintf(stderr, "difference on line %d\n", lineno);
                                printf("%s\n%s\n", line1, line2);
                                return STATUS_FILES_DIFFER;
                        }
                        else
                        {
                                if(strchr(line1, '\n'))
                                {
                                  eol = 1;
                                }
                        }
                }
        }
}
gribozavr is offline  
Old 2005-07-14, 00:25   #14
cjohnsto
 
Jun 2005

3·5 Posts
Default

gribozavr it is good that you found a bug and fixed it. I did however intentionally avoid string functions. I wanted to minimise library use to make it as portable as possible (I know the string ibrary is fairly standard/common and it made things harder). Feel free to expand the usage/testing even more I just wanted to get something out there for Wacky to use. It is hardly my best coding example :)

In short, good work.
cjohnsto is offline  
 

Thread Tools


Similar Threads
Thread Thread Starter Forum Replies Last Post
OPN Project Roll Call ThomRuley Factoring 14 2019-05-25 00:12
Team_Italia call for participants ET_ Teams 6 2018-12-18 12:08
What do you suppose they'll want to call it? schickel Science & Technology 6 2010-04-18 10:36
Call me lazy but... davieddy Puzzles 19 2009-10-06 05:41
Call to arms em99010pepe No Prime Left Behind 2 2008-11-26 13:21

All times are UTC. The time now is 18:36.


Sun Nov 28 18:36:57 UTC 2021 up 128 days, 13:05, 0 users, load averages: 0.89, 1.01, 1.07

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2021, Jelsoft Enterprises Ltd.

This forum has received and complied with 0 (zero) government requests for information.

Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation.
A copy of the license is included in the FAQ.