0

I am trying to create a function which takes a file name from the user and checks if it exists, as long as it does not exist I wish to re-ask the user to input a file until it finds a file that does exist. Finally, I wish to return the name of that file to the main in order to use in a different function.

I've created a function which I thought would work but it seems that I may have a problem with calling the variable and not inputting the file name directly. (I'm not positive that that is the issue).

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

char* fileCheck();
char* fileCheck()
{
    char* fileName;
    printf("Please enter a file name: ");
    gets(fileName);
    while (access(fileName, F_OK) == -1)
    {
        printf("The File %s was not Found\nPlease enter a new file name: ", fileName);
        gets(fileName);
    }
    return fileName;
}

int main (void)
{
    fileCheck();
    return 0;
}

I expect the output of the function to be the valid (existing) file name. In actuality I am receiving a garbage number exit code.

  • 1
    `char* fileName; gets(fileName);` - there is no memory behind `fileName` pointer. – KamilCuk May 22 '19 at 08:27
  • 2
    [Why you shouldn't use `gets`](https://stackoverflow.com/questions/1694036) – user3386109 May 22 '19 at 08:32
  • Think about separating interface and implementation. Interface is your interaction with the user. Where you get the file name. Implementation is your check of whether the file exists. You may have other instance where you have the file name and simply want to check if it exists. You don't want `"Please enter a file name: "` popping up all the time. So separate your request for a filename into a separate function, then pass the filename as a parameter to your function that checks if it exists. – David C. Rankin May 22 '19 at 08:41
  • Possible duplicate of [What's the best way to check if a file exists in C?](https://stackoverflow.com/questions/230062/whats-the-best-way-to-check-if-a-file-exists-in-c) – bruno May 22 '19 at 08:50
  • @bruno, I saw this question before posting my own, that question did not help me because I am trying to pass the file name as an argument into the function. I didn't know how to do so. – EthanCode26 May 22 '19 at 09:13
  • @EthanCode26 a filename is just a `char*`, it is given in arg in the code of the duplicate question (`int exists(const char *fname)`), where is the problem ? – bruno May 22 '19 at 09:15

1 Answers1

6

gets wants room, you can not use gets with an unallocated space, should be char filename[SOME_SIZE];

On the other hand, do not use gets since it is no longer part of the language, instead use fgets and strip the trailing newline.

Read this on how to trail the newline Removing trailing newline character from fgets() input

kiran Biradar
  • 12,700
  • 3
  • 19
  • 44
David Ranieri
  • 39,972
  • 7
  • 52
  • 94
  • Thank you @Keine Lust, how would you recommend allocating space for it. Should I use malloc(fileName* sizeof(char)) ... ? – EthanCode26 May 22 '19 at 08:32
  • 1
    If you don't know before hand the maximum size of the line then yes, use `malloc`, some implementations defines the maximum size of a line in `stdin` with `LINE_MAX`, you can check if your compiler defines it as an extension and in this case you can use this value with a fixed array. – David Ranieri May 22 '19 at 08:35
  • Just fix some reasonable size for the maximal file name length for example 300. – Jabberwocky May 22 '19 at 08:40
  • Thank you; so I must know how much space to allocate in order not to waste memory. Any suggestions on how to do so? – EthanCode26 May 22 '19 at 08:42
  • @EthanCode26 in this case you can use `getline` (or reimplement-it if not available in your libs), take a look to https://github.com/lattera/freebsd/blob/master/contrib/file/getline.c – David Ranieri May 22 '19 at 08:44
  • @EthanCode26 using a fixed size of say 300 bytes it not wasting memory, especially if `filename` is a local variable. But anyway, if you have functions such as `fread`, your platform is most likely not very restricted in terms of memory. – Jabberwocky May 22 '19 at 09:05