-2

As the title says I need to compare 2 files.If a line comes by ,that isnt the same between this 2 files,print that line (From both files).The code is giving a don't send error.I can't seem to be able to find the error in my code.

#include <stdio.h>
#include <string.h>
#define MAX 1000

int main(int argc, char *argv[]) {
    char c1, c2;
    char s1[MAX], s2[MAX];
    char *p1;
    char *p2;
    FILE *fp1;
    FILE *fp2;
    fp1 = fopen(argv[1], "r");
    fp2 = fopen(argv[2], "r");
    p1 = s1;
    p2 = s2;
    if (argc != 3) {
        printf("Wrong use of program \n ");
        return -1;
    }
    if (fp1 == NULL || fp2 == NULL) {
        printf("One or both of the files can't be used \n ");
        return -1;
    }
    while ((c1 = getc(fp1)) != EOF || (c2 = getc(fp2)) != EOF) {
        *p1 = c1;
        *p2 = c2;
        p1++;
        p2++;

        for (c1 = getc(fp1); c1 != '\n'; p1++) {
            *p1 = c1;
        }
        *p1 = '\0';

        for (c2 = getc(fp2); c2 != '\n'; p2++) {
            *p2 = c2;
        }
        *p2 = '\0';
        if (!(strcmp(s1, s2))) {
            printf("%s \n ", s1);
            printf("%s \n ", s2);
            return 0;
        }
    }
    return 0;
}
Lind
  • 277
  • 2
  • 5
  • 16
  • 4
    A *don't send error*? – Tchoupi Mar 16 '13 at 22:07
  • Compile with all warnings and debugging information (e.g. `gcc -Wall -g` on Linux) and *learn how to use the debugger* (e.g. `gdb` on Linux). – Basile Starynkevitch Mar 16 '13 at 22:08
  • 1
    For starters, I'd be looking at where you assign strings to `s1` and `s2`. – Joe Mar 16 '13 at 22:10
  • 1
    What's wrong with 2 `fgets()` and a `strcmp()` in a `while` loop? – pmg Mar 16 '13 at 22:12
  • You probably want to clear both `s1` and `s2` at start using `memset`. Then, use the debugger (and step by step) to display them. Notice that your program cannot work on files with huge lines (with more than 1000 chars on one line). Remember that getting the source code compiled is the easy part, debugging is the real fun. – Basile Starynkevitch Mar 16 '13 at 22:13
  • ok will try that one at first.The program does compile,havent tried debugging it though – Lind Mar 16 '13 at 22:15
  • 1
    Also consider what will happen if your file either ends in a single line-feed, or a line which is not terminated with a line-feed... – JasonD Mar 16 '13 at 22:16
  • More importantly, what type does [fgetc](http://pubs.opengroup.org/onlinepubs/009604599/functions/fgetc.html) return? int... What is the range of potential return values? `[ EOF, 0..UCHAR_MAX ]`. Assuming char is signed, can it represent UCHAR_MAX? Assuming char is unsigned, will `(c2 = getc(fp2)) != EOF` ever be false? Please, just use an `int` to store the return value of getc. – autistic Mar 16 '13 at 22:42

2 Answers2

2

If the two files are text files then, honestly, I would start from scratch with a much simpler program that uses fgets() rather than getc() and compares line by line using strcmp() rather than character by character. There are just too many errors in the code as it is - you will complete the task more quickly if you discard what you have and start again with the simpler solution.

By the way, strcmp returns zero if the two strings are the same, non-zero if they are different.

jarmod
  • 71,565
  • 16
  • 115
  • 122
1

On the two for loops you have the getc on the initialisation part of the loop, it will put a character in c1 and c2 once and then do the loop until you go beyond the limit of s1 and s2 through your p1 and p2 pointers. Since the c1 != '\n' is never met unless your first character in the line is a '\n' it will probably throw a segmentation fault error.

On the while, at least with gcc and on my system, it does lazy evaluation (EDIT: Not lazy but short-circuit evaluation, see comments) and the c2 = getc(fp2) part is not executed if the other part was true.

You also don't reset p1 and p2 after each line.

strcmp returns 0 if both strings are equal, and in C, 0 is false and non-zero is true, so you are exiting on the first match.

Here is a barely functioning version of your code, you still need to work on it and take into account cases like one file being shorter than the other, one line in a file being bigger than 1000 characters (as it is right now it would overflow s1 or s2), etc.

#include <stdio.h>
#include <string.h>
#define MAX 1000

int main(int argc, char *argv[]) {
  char c1, c2;
  char s1[MAX], s2[MAX];
  char *p1;
  char *p2;
  FILE *fp1;
  FILE *fp2;
  p1 = s1;
  p2 = s2;
  if (argc != 3) {
    printf("Wrong use of program \n ");
    return -1;
  }
  fp1 = fopen(argv[1], "r");
  fp2 = fopen(argv[2], "r");
  if (fp1 == NULL || fp2 == NULL) {
    printf("One or both of the files can't be used \n ");
    return -1;
  }
  c1 = getc(fp1);
  c2 = getc(fp2);
  while ((c1 != EOF) && (c2 != EOF)) {
    for (; c1 != '\n'; p1++) {
        *p1 = c1;
        c1 = getc(fp1);
    }
    *p1 = '\0';

    for (; c2 != '\n'; p2++) {
        *p2 = c2;
        c2 = getc(fp2);
    }
    *p2 = '\0';
    if ((strcmp(s1, s2)) != 0) {
        printf("%s\n", s1);
        printf("%s\n", s2);
        return 0;
    }
    c1 = getc(fp1);
    c2 = getc(fp2);
    p1 = s1;
    p2 = s2;
  }
  if (c1 != EOF || c2 != EOF)
    printf("One of the files ended prematurely\n");
  return 0;
}
Jorge Núñez
  • 1,703
  • 12
  • 17
  • Thanks thats what I needed.I know that if a line is bigger than 1000 it will cause an error,I just wanted to test the code with less lines as for now. – Lind Mar 17 '13 at 09:42
  • 1
    To clarify: the C and C++ languages define what happens executing if (x || y) when x is non-zero - specifically, y is not evaluated (it does not need to be, because x is 'true'). It's not "lazy evaluation" and it's not "at least with gcc and on my system". It's defined in the language; it's always. – jarmod Mar 23 '13 at 01:41
  • @jarmod Thanks for the clarification. My bad, I got the wrong concept there, it's called "short-circuit evaluation", isn't it? – Jorge Núñez Mar 23 '13 at 15:54
  • Yes, that's it. It applies to &&, to ||, and to the ternary operator ? as in (a > b) ? a : b. – jarmod Mar 23 '13 at 19:17