Segmentation fault while using ferror() in a simple program. Why? - c

Why is the following code giving segmentation fault?
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *file;
file = fopen("text","r");
if (file == NULL) printf("Error READING FILE");
if (ferror(file)) printf("error reading file"); //line 9
return 0;
}
Doing backtrace in gdb gives:-
> #0 0x00007ffff7ad9d30 in ferror () from /lib/libc.so.6
> #1 0x00000000004005fa in main () at test.c:9

file is NULL. You're not seeing the first printf because the program crashes before stdout is flushed.

If fopen returns NULL, then the file isn't open; you're passing NULL in to ferror, which is invalid. You don't have an open file to pass in; that's what NULL means, that it couldn't give you a file pointer. ferror is for getting errors related to reading and writing the file, once it has actually been opened and you have the file to work with.
If fopen fails, and you want to get more information about why, you need to check the errno global variable, defined in errno.h.
#include <errno.h>
// ...snip...
if (file == NULL)
printf("Error READING FILE: %s\n", strerror(errno));
This example shows how to fetch a string describing the error; you could also compare the value in errno against one of the possible values it could have, and do something different depending on what the error is. See the fopen man page, or the POSIX spec, for a list of possible errors to compare against. Here's how you could check against various possible errors:
if (file == NULL) {
int error = errno; // copy it so other calls like printf don't modify it
printf("Error READING FILE: %s\n", strerror(error));
switch (error) {
case EACCESS:
// access was denied
break;
case ENOENT:
// the file or one of its ancestors doesn't exist
break;
// etc...
}
}
(this is an expansion of something I originally wrote in a comment on another answer)

If file is equal to NULL on line 9, then the Seg Fault will occur during the ferror() call.
If there the file is NULL (as determined on line 8), then you shouldn't perform line 9.
Your line 8 code should be changed as such:
if (file == NULL)
{
printf("Error READING FILE");
return 1;
}
NB: i could be very wrong about this, it's been a while since i've done C/C++

Related

canĀ“t open txt file

#include <stdio.h>
#include <stdlib.h>
int main()
{
char c[1000];
FILE *fptr;
if ((fptr = fopen("program.txt", "r")) == NULL)
{
printf("Error! opening file");
// Program exits if file pointer returns NULL.
exit(1);
}
// reads text until newline
fscanf(fptr,"%[^\n]", c);
printf("Data from the file:\n%s", c);
fclose(fptr);
return 0;
}
Output is Error! opening file
I have program and txt file in same dir.
How can I direct access to that file?
To diagnose, use the system command to issue a ls or dir depending on your platform. That will tell you where you are running from. Odds are it is a different location than the files you are trying to open.
As suggested in the comment, try replacing printf with perror
if ((fptr = fopen("program.txt", "r")) == NULL)
{
perror("Error");
// Program exits if file pointer returns NULL.
exit(1); // Exiting with a non-zero status.
}
perror prototype is
void perror(const char *str)
where str is the C string containing a custom message to be printed before the error message itself.
However some causes of the of the file not being read are
File is not present in the current working directory. If this is the case, rectifying the path should fix the issue.
The program might not have the permissions to read from the file usually because of a setting related to discretionary access control. Perhaps do a chmod with file?
I made a quick run of your program on TURBOC++ by Borland and it executed without complaining any sort of Warning or Error
As mentioned in the earlier posted answers, you should replace printf by perror
CURRENT REPLACE BY
printf("Error! opening file"); perror("Error! Opening File.");
As in your case of file not found printf("Error! opening file"); will result in :
Error! Opening file.
However in case of perror("Error! Opening File."); if the file program.txt does not exist, something similar to this may be expected as program output
The following error occurred: No such file or directory
The difference is obvious from above explanations.
Regarding your program, I am making an assumption that either your path to the file is wrong or there is some problem with your compiler.
Try to open your file in w+ mode also to ensure that the file exist.

fseek() API in C and error code

I am trying to run below code and expecting error as [EBADF] The stream is NULL
#include <stdio.h>
int main ()
{
FILE *fp;
char ch;
fp=fopen("test33.txt","r");
fseek(fp,0L,SEEK_SET);
while((ch=fgetc(fp))!=EOF)
putchar(ch);
}
Output:
/home/akhils/file_dir#./a.out
Memory fault(coredump)
Through which utility can I see error [EBADF]? I am running this C Program on HP-UX box and using a C++ compiler by HP.
I rewrote the code as below as per suggestion:
#include<stdio.h>
#include<errno.h>
extern int errno;
int main ()
{
FILE *fp;
int val;
char ch;
fp=fopen("test33.txt","r");
if(fp==NULL)
printf("\n Error code for fopen is : %d\n",errno);
else
{
val=fseek(fp,0L,SEEK_SET);
if(val!=0)
val=errno;
else {
while((ch=fgetc(fp))!=EOF)
putchar(ch);
}
printf("\nError code for fseek is %d\n",val);
}
}
Output : /home/akhils/file_dir#./a.out
Error code for fopen is : 2
My question is and sorry if I am asking it in wrong sense that how would I know that error is "[EBADF] The fildes argument is not a valid file descriptor." Note : EABDF is ALSO error set for fopen() when a NULL pointer is returned by fopen i.e in case of unsuccessfull completion of fopen().
First and foremost, you should be checking for the success of fopen(), as if it fails, passing the returned pointer (NULL) will invoke undefined behaviour in fseek(). You should not be using the returned pointer any further if fopen() failed.
That said, to detect the error in fseek() itself, you should be checking the return value of fseek() for success (or error). In case, fseek() is failure, it will set the errno variable. You can check the same against the EBADF.
You don't need any utility as such to check the error code. You can use #include <errno.h> with you code and you can access the errno variable value.
From the man page for fseek(),
[...] fgetpos(), fseek(), fsetpos() return 0, and ftell() returns the current offset. Otherwise, -1 is returned and errno is set to indicate the error.
and regarding the EBADF, as you mentioned,
EBADF
The stream specified is not a seekable stream.
You should at least check if the file can actually be opened:
...
fp=fopen("test33.txt","r");
if (fp == NULL)
{
// abort if file cannot be opened
printf("Cannot open file");
return 1;
}
...

Runtime error during file operation in C

I am trying to run a C code for file opening and whenever I do that I get a debug assertion failed message.
Here is my code:
#include<stdio.h>
#include<stdlib.h>
void main()
{
FILE *fp1;
printf("program to demonstrate file operations");
fp1 = fopen("try1.txt","r");
if (feof(fp1))
{
printf("Yes");
}
else
printf("No");
printf("%f",fp1);
getchar();
}
The Debug assertion failure might be caused by fp1 being null.
This will happen if the file could not have been opened.
Change
if (feof(fp1))
to
if (fp1 && !feof(fp1))
That is check for the return value of fopen(). If unable to open the file it would return NULL.
Edit:
Check if the file is in the same directory as that of exe/binary.
Check whether you have the permission to access the file.
Check the return value of
fp1 = fopen("try1.txt","r");
first. It is fare to check the return values of all standard functions( with proper return values) before proceeding to next step. In this case "fp1" should not be NULL. Please check the file location or check whether file is present in current directory.
Try to check if the file is opened correctly or not
check if( fp==NULL) using an if condition
if fp==NULL is true, file is not being opened correctly
Before using feof() on fp.
Ensure that fopen() succeeded.
#include <string.h> /* For strerror() */
#include <errno.h> /* For errno */
#include <stdlib.h> /* For exit() */
fp = fopen ("FaultyFile.txt", "r");
/* Add Error-checking */
if (NULL == fp)
{
printf ("Error No : [%d]\n", errno);
printf ("Error Msg: [%s]\n", strerror(errno));
exit (EXIT_FAILURE);
}
From man(3) fopen:
Return Value: Upon successful fopen() return a FILE pointer. Otherwise, NULL is returned and errno is set to indicate the error.

C segmention fault when opening file

This seems to be a really simple one, but I can't figure it out after not touching C programming in four years.
I was trying to open a file in main()
int main(int argc, const char * argv[])
{
FILE * fp = fopen("data.txt","r");
...
return(0)
}
The program compiled, but when I tried to run it in gdb, the following error occurs.
Program received signal SIGSEGV, Segmentation fault.
0x00000000004016c6 in main ()
when the program is trying to open the file "data.txt". What could cause the error? Thanks!
I suspect your error lies in this bit of code:
...
In other words, there's nothing in the other code shown that appears to be wrong.
The most likely case is that the file doesn't exist, or it doesn't exist in the directory where the program is running (which, if you're in an IDE, usually turns out to be somewhere other than you think it is).
And, in that case, you're getting NULL from the fopen, then later using it, something like:
FILE *fp = fopen ("no_such_file.txt", "r");
int ch = fgetc (fp);
You should generally check return values from all functions that use them to indicate success or failure:
#include <stdio.h>
int main (void) {
FILE *fp = fopen ("no_such_file.txt", "r");
if (fp == NULL) {
perror ("Opening no_such_file.txt");
return 1;
}
// You can use fp here.
puts ("It worked.");
fclose (fp);
return 0;
}
What could cause the error?
The most likely cause of the error is that the file data.txt could not be opened (e.g. because it doesn't exist, or it's not in the current directory, or your program doesn't have permission to read it). That will cause fopen() to return NULL. Then if your code (in the ... section) tries to call fread() or fgets() or whatever and passes in the NULL pointer, that will cause a crash. You need to check the value returned by fopen() to make sure it is non-NULL before trying to use it.

Why does fopen("any_path_name",'r') not give NULL as return?

While debugging some code I got something like below:
#include<stdio.h>
int main()
{
FILE *fb = fopen("/home/jeegar/","r");
if(NULL == fb)
printf("it is null");
else
printf("working");
}
Here in fopen I gave a somewhat valid path name but not a filename. Shouldn't fopen return NULL then? But it does not return null!
Edit:
If I give path of valid directory in fopen then it will print working:
If I give path of invalid directory in fopen then it will print it is null
Edit:
spec says
Upon successful completion, fopen() shall return a pointer to the object
controlling the stream. Otherwise, a null pointer shall be returned.
so here whether error code set or not, it MUST return NULL
And error code setting is an extansion to ISO C standard standard.
ERROR IS ALSO NOT GOING TO SET HERE
#include<stdio.h>
#include <errno.h>
int main()
{
errno = 0;
FILE *fb = fopen("/home/jeegar/","r");
if(fb==NULL)
printf("its null");
else
printf("working");
printf("Error %d \n", errno);
}
OUTPUT IS
workingError 0
I think that in Unix everything (directories included) is considered to be file so fopen should work on them.
The posix man page man 3p fopen says, in the section ERRORS:
The fopen() function shall fail if:
[...]
EISDIR The named file is a directory and mode requires write access.
(Emphasis mine). Since you are not requesting write access, and chances are that the path you use is a directory, the function does not fail.
About what can you use with a FILE* that refers to a directory, I have no idea.
As you might be very well aware that pretty much everything on Linux system is a file, if not a file then its a process (corrections & remarks welcome :) ) Directory is treated like a file which lists other files (Reference from TLDP); so opening to read a directory as a file is a valid operation and thus you do not get any error. Although trying to write to it is not allowed, so if you open directory in write or append mode, the fopen operation will fail (this has been very well mentioned is other responses & link to fopen documentation). Most of the file operation like read & write operations on this file stream will fail with the error stating that its a directory. Only use which could be found was finding the size of the file (directory in this case) using fseek to SEEK_END & ftell (which will most likely give a result of 4096).
Regarding using errno to get meaningful messages, you can use perror which is in stdio.h & pass message which will be added before the error message or strerror which is in string.h & pass errno which is in errno.h
Hope this helps!
How to check that errno?
You can check errno for example:
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
FILE *fp;
errno = 0;
fp = fopen("file.txt", "r");
if ( errno != 0 )
{
// Here you can check your error types:
perror("Error %d \n", errno);
exit(1);
}
}
Error types you can find at http://pubs.opengroup.org/onlinepubs/009695399/functions/fopen.html Error section.

Resources