You have several problems in your code. i will list them below:
- In
c
programming we declare variables in the scope begin. and initialize them if we need so. you have a mixture of declerations and code.
count
variable non initialized!! you have entered the while loop with garbage value in count. UB (Undefined behavior) - in each run you will get different values.
- you didnt check the return value of
fopen
!! you must check if the operating system succed in opening the file you have requested to manipulate.
- regarding asking a question in stackoverflow, your code is not complete and you didnt post all of it.
Now lets try to learn new topics regarding working with IO streams.
return value of function fscanf
The value EOF
is returned if the end of input is reached before
either the first successful conversion or a matching failure occurs
.
EOF
is also returned if a read error
occurs, in which case the
error indicator for the stream (see ferror(3)
) is set, and errno
is set indicate the error.
This is how check if errors ocured while working with the file we are reading:
int ferror(FILE *stream);
The function ferror() tests the error indicator for the stream pointed
to by stream, returning nonzero if it is set. The error indicator can
only be reset by the clearerr() function.
And in this function bellow we get a human readble error, not just an errnor number!
explain_ferror
const char *explain_ferror(FILE *fp);
The explain_ferror function is used to obtain an explanation of an
error returned by the ferror(3) system call. The least the message
will contain is the value of strerror(errno), but usually it will do
much better, and indicate the underlying cause in more detail.
The errno global variable will be used to obtain the error value to be
decoded.
#include <stdlib.h>
#include <stdio.h>
#include <libexplain/ferror.h> /* for the non standard const char* explain_ferror(FILE* fp); */
int main(void)
{
FILE *fp;
char text;
int count = 0;
fp = fopen("txt.txt", "r");
if(fp == NULL)
{
perror("fopen failed"); /*write to standard error*/
exit(EXIT_FAILURE);
}
while (fscanf(fp, "%c", &text) != EOF)
{
++count;
}
if (ferror(fp)) /* nonzero return if error occured */
{
fprintf(stderr, "%s\n", explain_ferror(fp));
exit(EXIT_FAILURE);
}
printf("%d", count);
return 0;
}
Since the const char *explain_ferror(FILE *fp);
is not GNU standard function, i am posting a GNU standard functions in the code snippet below:
char *strerror(int errnum);
strerror
is standard library c function which returns a pointer to a string that describes the error code passed in the argument errnum
. Be aware that this function is not Thread safe
. for thread safe function use The strerror_r()
.
Return Value
The strerror(), function return the appropriate error description string, or an "Unknown error nnn" message if the error number is unknown.
Since POSIX.1-2001
and POSIX.1-2008
requires that a successful call to strerror() shall leave errno
unchanged, and note that, since no function return value is reserved to indicate an error, if we wishe to check for errors we should initialize errno to zero before the call (by calling void clearerr(FILE *stream);
, and then check errno after the call.
#include <string.h>
#include <errno.h>
#include <stdio.h>
...
clearerr(fp); /* clear previous seted errno */
while (fscanf(fp, "%c", &text) != EOF)
{
++count;
}
if (ferror(fp)) /* nonzero return if error occured */
{
fprintf(stderr, "%s\n", strerror(errno));
exit(EXIT_FAILURE);
}
...
Finally:
man pages (or man7) or typing man <enter_string_here>
in terminal on linux shall clear all the q.marks.
for further reading go to:
explain_ferror
ferror
fscanf