Search code examples
cstringfopenstrstr

Why does fopen() not recognize my file's name?


The programm should be able to open a file like myFile.txt, alltough it's real name is myFile without the extension .txt. So I wrote the function called removeFileExtension() in order to achieve that.

It does open my file by copying the string from text into filename:

strcpy(filename,text);
FILE *fp = fopen(filename, "r");

So I tried to check what the difference between text and my processed string from removeFileExtension is.

To check if it even works I mate a function called strComparison(), which returns either 0 when it is qual or 1 if unequal. The thing is, after removing the file extension, it shows that both strings are qual, but I am still not able to open the file.

When I type in ./a.out myFile.txt my comparison function returns 0, it is equal, but fopen() still is not able to open the file, respectively I allways get a Segmentation fault.

Does anyone see the problem here? Why am I getting a Segmentation fault?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void removeFileExtension(char *haystack);
int strComparison(char *one, char *two);

int main(int argc, char const *argv[])
{
  //----------------------------------------------------------------------------
  // CHECK INPUT VALIDITY
  //
  if (argc != 2)
  {
    printf("Usage: ./ass2 [file-name]\n");
    return 1;
  }


  //----------------------------------------------------------------------------
  // OPEN FILE (INITIAL)
  //
  char filename[32];
  strcpy(filename, argv[1]);
  FILE *fp = fopen(filename, "r");                                       //FOPEN
  //FILE *fp = fopen("start_of_story\0txt", "r");   // this way does work
  if (fp == NULL)
  {
    // IF NOT FOUND: REMOVE EXTENSION
    removeFileExtension(filename);
    char text[] = "myFile\0";
    int ret_val = -1;
    ret_val = strComparison(filename, text);
    if (ret_val == 0)
      printf("[DEBUG] equal\n");
    else
      printf("[DEBUG] unequal\n");

    printf("[DEBUG] ret_val: %d\n", ret_val);
    printf("[DEBUG] '%s'\n", filename);
    FILE *fp = fopen(filename, "r");                                     //FOPEN

    // IF STILL DOESN'T WORK: ERROR
    if (fp == NULL)
    {
      printf("[ERR] Could not read file %s.\n", filename);
      return 3;
    }
  }


  //--------------------------------------------------------------------------
  // READ DATA (INITIAL)
  //
  int bufsize = 1024;
  char *buffer = malloc(bufsize * sizeof(char));                      //MALLOC
  if (!buffer)
  {
    printf("[ERR] Out of memory.\n");
    return 2;
  }
  fseek(fp, 0, SEEK_SET);
  fread(buffer, bufsize, 1, fp);

  printf("[DEBUG] %s\n", buffer);
  fclose(fp);                                                           //FCLOSE

  free(buffer);
  buffer = NULL;
  return 0;
}

void removeFileExtension(char *haystack)
{
  char needle[1] = ".";
  char *retp;   // return pointer
  retp = strstr(haystack,needle);
  if (*retp == '.')
  {
    while (*retp != '\0')
    {
      *retp++ = '\0';
    }
    printf("[DEBUG] %s\n", haystack);
  }
}

int strComparison(char *one, char *two)
{
  do
  {
    printf("[DEBUG] '%c' == '%c'\n", *one, *two);
    if (*one++ != *two++)
    {
      return 1; // return 1 if unqual
    }
  }
  while ( (*one != '\0') || (*two != '\0') );
  return 0; // return 0 if qual
}

Resulting output:

user@host ~/Desktop $ ./a.out myFile.txt
[DEBUG] myFile
[DEBUG] 'm' == 'm'
[DEBUG] 'y' == 'y'
[DEBUG] 'F' == 'F'
[DEBUG] 'i' == 'i'
[DEBUG] 'l' == 'l'
[DEBUG] 'e' == 'e'
[DEBUG] equal
[DEBUG] ret_val: 0
[DEBUG] 'myFile'
[ERR] Could not read file myFile.
user@host ~/Desktop $

Solution

  • At least I found the problem:
    After removing the file's extension, I am still trying to open the old file pointer fp, which gave me the NULL-pointer back. The new file pointer inside the body of the if(fp == NULL){...} only exists inside the scope of the if-statement.

    So I created a test_pointer, which first looks if the file even exists, if not, he removes the extension. Than I try again to open the file, this time with fp.

    Thanks to everybody for the hints, especially to Sourav Ghosh for your improvement suggestions!

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    int removeFileExtension(char *haystack);
    
    int main(int argc, char const *argv[])
    {
      char filename[64];
      strcpy(filename, argv[1]);
    
    
      //----------------------------------------------------------------------------
      // CHECK INPUT VALIDITY
      //
      if (argc != 2)
      {
        printf("Usage: ./ass2 [file-name]\n");
        return 1;
      }
    
    
      //----------------------------------------------------------------------------
      // CHECK FILE EXISTENSE
      //
      FILE *test_pointer = fopen(filename, "r");                             //FOPEN
      if (test_pointer == NULL)   // if not found: remove extension
      {
        int ret_val = removeFileExtension(filename);
        if (ret_val == -1)
        {
          printf("[ERR] Could not remove file extension.\n");
          return 3;
        }
      }
    
    
      //----------------------------------------------------------------------------
      // OPEN FILE (INITIAL)
      //
      FILE *fp = fopen(filename, "r");                                       //FOPEN
      if (fp == NULL)   // if still doesn't work: error
      {
        printf("[ERR] Could not read file %s.\n", filename);
        return 3;
      }
    
    
      //----------------------------------------------------------------------------
      // READ DATA (INITIAL)
      //
      int bufsize = 1024;
      char *buffer = malloc(bufsize * sizeof(char));                        //MALLOC
      if (!buffer)
      {
        printf("[ERR] Out of memory.\n");
        return 2;
      }
      fseek(fp, 0, SEEK_SET);
      fread(buffer, bufsize, 1, fp);
      fclose(fp);                                                           //FCLOSE
    
      printf("[DEBUG] %s\n", buffer);
      free(buffer);                                                           //FREE
      buffer = NULL;
      return 0;
    }
    
    
    int removeFileExtension(char *haystack)
    {
      char needle[] = ".";
      char *retp;   // return pointer
      retp = strstr(haystack,needle);
      if(!retp)     // to prevent UB
        return -1;
    
      if (*retp == '.')
      {
        while (*retp != '\0')
        {
          *retp++ = '\0';
        }
        printf("[DEBUG] %s\n", haystack);
      }
      return 0;
    }