0

So I'm working on a project, and I need to check whether or not a certain file contains the contents of another file.
I made a function in c (It's c not c++) to try and to it but it seems to get into an infinite loop and not work overall, I tried using the Visual Studio debugger, and it didn't give me more info.

Note: I am including stdlib.h

the code:


int findFileInFile(const char* wherePath, const char* whatPath)
{
    FILE* fpBigger = fopen(wherePath, "r");
    FILE* fpSmaller = fopen(whatPath, "r");

    if (fpBigger != NULL && fpSmaller != NULL)
    {
        unsigned char cs = 0;
        unsigned char cb = 0;

        while ((cb = fgetc(fpBigger)) != EOF)
        {
            cs = fgetc(fpSmaller);

            if (cs == EOF)
                return 1;

            if (cs != cb)
            {
                fseek(fpSmaller, 0L, SEEK_SET);
            }
        }

        return 0;
    }
    else
    {
        printf("File names are wrong!\n");
        exit(-1);
    }
}

Thank you.

  • `EOF` is a negative value, so it will never be equal to `unsigned char` value. Use `int` to assign what is returned from `fgetc()`. – MikeCAT Jun 15 '21 at 13:54
  • 1
    [Why must the variable used to hold getchar's return value be declared as int?](https://stackoverflow.com/q/18013167/995714) – phuclv Jun 15 '21 at 14:08
  • `EOF` may also be returned by `fgetc()` because of error, you should check for that. – HAL9000 Jun 15 '21 at 15:14
  • "File names are wrong!" is a truly bizarre error message. If `fopen` fails, tell the user the reason. eg: `if( (fpBigger = fopen(wherePath, "r")) == NULL ){ perror(wherePath); ...}` – William Pursell Jun 15 '21 at 17:51

1 Answers1

1

I guess this is what you're looking for:

#include <stdio.h>
#include <stdlib.h>
int findFileInFile(const char *wherePath, const char *whatPath)
{
  FILE *fpBigger = fopen(wherePath, "rb");
  FILE *fpSmaller = fopen(whatPath, "rb");

  if (fpBigger != NULL && fpSmaller != NULL)
  {
    unsigned char cs = 0;
    unsigned char cb = 0;
    int s;
    int b;
    while (1)
    {
      b = fgetc(fpBigger);
      s = fgetc(fpSmaller);
      if (s == EOF && b == EOF) //if both return values from fgetc are EOF, it means you've reached the end of the file which wouldn't have been possible if both of the files weren't equal
      {
        return 1;
      }
      else if (s == EOF || b == EOF)
      {
        return 0;
      }
      cs=(unsigned char)s; //casting the int to unsigned char
      cb=(unsigned char)b; //casting the int to unsigned char
      if (cs != cb) //compare the characters gotten from the files, if not equal, return 0
      {
        return 0;
      }
    }
  }
  else
  {
    printf("File names are wrong!\n");
    exit(-1);
  }
}
int main()
{
  printf("%d", findFileInFile("file1.txt", "file2.txt"));
}

Last but not the least, you can also use feof() to check if the end of file stream has been reached.

Edit: (this may not be the most optimal solution but it checks if the bigger file contains the smaller file)

#include <stdio.h>
#include <stdlib.h>
int findFileInFile(const char *wherePath, const char *whatPath)
{
  FILE *fpBigger = fopen(wherePath, "rb");
  FILE *fpSmaller = fopen(whatPath, "rb");

    unsigned char cs = 0;
    unsigned char cb = 0;
    int s;
    int b;
    int loc;
    if (fpBigger != NULL && fpSmaller != NULL)
    {
      s = fgetc(fpSmaller);
      cs=(unsigned char)s;
      while((b=fgetc(fpBigger))!=EOF){ //checks for the first instance of the first character of the smaller file in the bigger file
        cb=(unsigned char)b;
        if(cs==cb){
            loc=ftell(fpBigger)-1; //set loc to the position where the first character of the smaller file is found in the bigger file
            break;
        }
      }
      if(b==EOF){ //if the character is not found, return 0
          return 0;
      }
      fseek(fpBigger,loc,SEEK_SET);
      rewind(fpSmaller);
      while((b=fgetc(fpBigger))!=EOF){
          if((s=fgetc(fpSmaller))==EOF){ //check if the end of smaller file is reached, and return 1 if true
              return 1;
          }
          cs=(unsigned char)s;
          cb=(unsigned char)b;
          if(cs!=cb){
              rewind(fpSmaller); //if the characters gotten from both the files are not equal, go to the very beginning of smaller file
              loc++; //increase the position to start the search from in the bigger file by 1
              fseek(fpBigger,loc,SEEK_SET);
          }
      }
      if(b==EOF&&fgetc(fpSmaller)==EOF){
        return 1;
      }
      return 0;
    }
  else
  {
    printf("File names are wrong!\n");
    exit(-1);
  }
}
int main()
{
  printf("%d", findFileInFile("file1.txt", "file2.txt"));
}
  • But this will check for the file only in the begging, kind of just checks if the files are equal, I want to check if a certain file contains in itself (not is the same file but **contains**) another file. – איתן טורפז Jun 17 '21 at 11:46
  • @איתןטורפז I hadn't understood your question properly before, I added a new block of code, I guess that's what you might be looking for. – JASLP doesn't support the IES Jun 17 '21 at 14:06