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 $
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;
}