Table of Contents
For this activity, you should revise the fwrite and fread functions and toupper
Section 4 from Reading and writing with files .
To read from a file a specific number of bytes, it is useful
the fread
function: size_t fread(void *restrict ptr,
size_t size, size_t nitems, FILE *restrict stream);
. This function
reads nitems
objects, each size bytes
long, from
the stream pointed to by stream
, storing them at the location
given by ptr
.
The fread
function returns the
number of objects read. If an error occurs, or the end-of-
file is reached, the return value is a short object count
(or zero).
As the fread
function does not distinguish
between end-of-file and error; callers must use feof()
and
ferror()
to determine which occurred.
The feof
function: int feof(FILE
*stream);
tests the end-of-file indicator for the stream pointed to
by stream, returning non-zero if it is set.
The inverse function of fread
is the
fwrite
function: size_t fwrite(const void *restrict ptr,
size_t size, size_t nitems, FILE *restrict stream);
This function writes nitems
objects, each
size
bytes long, to the stream pointed to by stream
, obtaining them from the location given by ptr
.
The fwrite
function returns the number of
objects written. The function fwrite()
returns a value less
than nitems
only if a write error has occurred.
The toupper
function converts a char to
uppercase int toupper (int c);
. The return value is the
character c
converted to uppercase or c
otherwise. This function is included in the library
ctype.h
.
Write a program with name
convert_to_uppercase.c
that implements the
following operations:
Check that the program is executing with two arguments. If that is not the case, print a message and terminate.
Open with reading permissions the file using as name the first argument given to the program. If the operation fails, notify with a message and terminate the execution.
Open with writing permissions the file using as name the second argument given to the program. If the operation fails, notify with a message and terminate the execution.
Reads SIZE bytes of the input file (first argument) using the fread
function and transforms each character into uppercase (use a loop, taking care of converting only the number of read bytes)
Writes using fwrite
the converted characters.
The program must convert all the file to uppercase.
Close the input and output files
Section 4 from Reading and writing with files .
You should know the following concepts:
To read from a file a specific number of bytes, it is useful
the fread
function: size_t fread(void *restrict ptr,
size_t size, size_t nitems, FILE *restrict stream);
. This function
reads nitems
objects, each size bytes
long, from
the stream pointed to by stream
, storing them at the location
given by ptr
.
The fread
function returns the
number of objects read. If an error occurs, or the end-of-
file is reached, the return value is a short object count
(or zero).
As the fread
function does not distinguish
between end-of-file and error; callers must use feof()
and
ferror()
to determine which occurred.
The feof
function: int feof(FILE
*stream);
tests the end-of-file indicator for the stream pointed to
by stream, returning non-zero if it is set.
The inverse function of fread
is the
fwrite
function: size_t fwrite(const void *restrict ptr,
size_t size, size_t nitems, FILE *restrict stream);
This function writes nitems
objects, each
size
bytes long, to the stream pointed to by stream
, obtaining them from the location given by ptr
.
The fwrite
function returns the number of
objects written. The function fwrite()
returns a value less
than nitems
only if a write error has occurred.
The mkstemp
function: int mkstemp(char
*template)
, generates a unique temporary file name from
template
.
The last six characters of template
must be
“XXXXXX” and these are replaced with a string that makes the
filename unique. The file is then created with mode read/write.
Since it will be modified, template
must not be
a string constant, but should be declared as a character array.
The mkstemp
function returns the file
descriptor fd of the temporary file or -1 on error. Notice that the file
descriptor is an int
.
In order to open a file using its file descriptor, you must
use the fdopen
function: FILE *fdopen(int fildes, const
char *mode)
This function behaves as the fopen
function,
but instead of opening a file using its path, it uses the file
descriptor.
In order to move the file position indicator for a stream,
the fseek function must be used: int fseek(FILE*stream,long offset,int
whence);
.
This function sets the file position indicator for the
stream pointed to by stream. The new position, measured in bytes, is
obtained by adding offset
bytes to the position specified by
whence
. If whence
is set to SEEK_SET
,
SEEK_CUR
, or SEEK_END
, the offset is relative to
the start of the file, the current position indicator, or end-of-file,
respectively.
The rewind
function: void
rewind(FILE*stream)
sets the file position indicator for the stream
pointed to by stream to the beginning of the file.
The remove
function: int remove(const
char *pathname)
, deletes a name from the file system.
The rename
function : int rename(const
char *oldpath, const char *newpath)
, renames a file, moving it
between directories if necessary.
Data of the scores of a group of students is stored in a file. This file has the following structure:
Where id_c
is the group identifier (4 bytes);
id_s
the student identifier (4 bytes); size_n
the
size of the name of the student, including the zero(4 bytes);
name
, the name of the student (including the
zero);n_scores
the number of scores stored for this student (an
integer of 4 bytes); score_i
, the i score of this student (4
bytes).
If n_scores
is equal to zero, the student has
no scores.
You are asked to:
Definition of the needed data structures to store all this information in a linked list.
Code a function that reads from the file and stores all this information in a linked list. This function has as input parameters the list where to store all this information and the filename.
Code a function that, given the data of a student
(id and name), inserts him/her at the begining of the file. This
function must check if the student data are already stored, and if
not, it must insert her/him with 0 scores. As input parameters, this
function has the student data and the filename. You must use the
mkstemp
function to create a temporary file.
Code a function that, given the data of a student
(id and name), deletes him/her (and all his/her data, including
scores) from the file. As input parameters, this function has the
student data and the filename. You must use the mkstemp
function to create a temporary file.