Nice first question. It can definitely be expanded on for additional learning in the future.
Improve Error Handling
Both the functions
getFile() could be changed to return int. This would allow the program to exit with the correct status.
int createFile(); // return EXIT_SUCCESS or EXIT_FAILURE
int getFile(); // return EXIT_SUCCESS or EXIT_FAILURE
int status = EXIT_SUCCESS; // EXIT_SUCCESS and EXIT_FAILURE are defined in stdlib.h
status = createFile();
if (status != EXIT_SUCCESS)
status = getFile();
getFile() the variable
filePointer is tested after fopen(). This is a good practice. In
createFile() the variable
filePointer is not tested, this is a bad practice. The C library function fopen() for
write can fail for a number of reasons:
- File exists and is protected.
- File exists and it is a directory.
- The program doesn't have sufficient privilege to write to the target directory.
There are more ways it can fail, this is a partial list. See full list of possible error codes. The C library function perror() can be used to report program error in the case of
I/O failures or the include file
errno.h can be included and the global variable errno will contain
the error code for better error messages as shown in this stackoverflow question.
These same error messages can be used to improve the error reporting in
getFile() as well.
The existing error message in
getFile() might be improved by adding the file name to the error message.
fprintf(stderr, "File %s not found.\n", fileName);
Error messages should generally be reported using
fprintf(stderr, FMT); rather than reporting the error
stdout using printf().
Inconsistent File Name Size
getFile() fileName can be up to 99 characters (strings must be null terminated),
createFile() it can be 39 characters, this is inconsistent and may confuse the user.
The code also doesn't tell the user how long the file name can be and that could be a
problem for the user. In neither case is the length of the string checked prior to use,
and that could lead to a number of errors including buffer overflow.
A better way to handle the file name size might be to define a symbolic constant using
#define MAX_FILE_SPEC_LENGHT 1024
The file name variable should be large enough to handle a full path as well as the file name.
Many systems define the maximum file name size based on the file system implementation. On Linux the
include file linux/limits.h defines that maximum file name size using PATH_MAX. Most operating systems
will have some way of defining it.
This line was flagged by my C compiler with a warning:
fgets (&filecontent, 1000, stdin);
The warning is Incompatible pointer types passing
char (*) to parameter of type
Since file content is an array of chars it only needs the name
filecontent rather than the address
filecontent, to use the address, it should be
Inconsistent Variable Naming Conventions
In the function
createFile() there are 3 variables, userfilename, filecontent and filePointer,
the variable filePointer is camelCase and is clear, userfilename and filecontent are not camelCase
and not quite as clear.