When I wanted to use fopen() to read a file in Debugging, fopen() always return NULL and I can't locate the error after trying:
I just run the code, and fopen() works well, getting what I want. (but failed in debugging)
I am sured that the file (hello.txt) exists
I write a simple code like:
#include<stdio.h>
int main()
{
FILE *fp;
char str[50];
fp = fopen("F:\\notes\\assign\\bonus\\hello.txt","r"); //this line
fgets(str, 50, fp);
printf("%s", str);
return 0;
}
this code doesn't work too. I make a breakpoint at "this line" and watch how the FILE *fp changes.
before:
fp: 0x00007ff663b31110 {hello.exe!void(* pre_cpp_initializer)()} {_Placeholder=0x00007ff663ac74a4 {hello.exe!pre_cpp_initialization(void)} }
after:
fp: 0x000001b7d6c3eb50 {_Placeholder=0x0000000000000000 }
you can see fopen() returns NULL;
I also tried freopen() and fopen_s(), but failed too.
For more information:
I use vscode. my compiler is "clang", my debugger is Windows VS so that I have to lauch vscode in Developer Cmd Prompt.
I would appreciate if anyone can help me. This disturbs me for a long time.
fp = fopen("F:\\notes\\assign\\bonus\\hello.txt","r"); //this line
A failure by fopen() (and many other standard library functions) will set errno to an error code indicating the error cause. You can turn that into a proper error message by adding code like this:
if ( fp == NULL )
{
perror( "Failed to open hello.txt" );
exit( 1 );
}
perror() will append a description of the error cause to the string you have given as argument, and print that to stderr. If you want to log the error message elsewhere, strerror() will write the error message to a string buffer.
Related
Trying to read from a file to use in a small game I've created. I'm using the fgets function. It's returning a Segmentation Fault, not sure why.
The file it's reading, just contains "20 10" in a txt file as this is the map size.
My readfile function is shown below
if (argc == 2) {
f = fopen("map.txt", "r");
if (NULL == f) {
printf("File cannot be opened.");
}
while (fgets(fileRead, 50, f) != NULL) {
printf("%s", fileRead);
}
fclose(f);
}
The if (argc == 2) can be ignored, this is just to make this section run, as I'm modifying a file so just running this function by satisfying that if statement.
I am fairly new to C, so apologies if I'm missing something minor. Worth noting I'm programming in C89 and using the -Wall -ansi -pedantic compile options, as this is University work and the tutors want us to do C89.
EDIT:
char userInput, fileRead[50];
FILE* f;
Declaration of variables.
Assuming that your problem is indeed in your posted code and not somewhere else in the program, then I believe that your problem is caused by the following issue:
After calling fopen, you check the return value of the function immediately afterwards, to verify that it succeeded. However, if it doesn't succeed and it returns NULL, all you do is print an error message to stdout but continue execution as if it succeeded. This will cause fgets to be called with NULL as the stream argument, which will invoke undefined behavior and probably cause your segmentation fault.
In the comments section, you raised the following objection to this explanation:
However it doesn't print the error message anyway and still segmentation faults, so I think the problem isn't here?
This objection of yours is flawed, for the following reason:
When a segmentation fault occurs, execution of the program is immediately halted. The content of the output buffer is not flushed. This means that output can get lost when a segmentation fault happens. This is probably what is happening in your case.
If you want to ensure that the output actually gets printed even in the case of a segmentation fault, you should flush the output buffer by calling fflush( stdout ); immediately after the print statement. Alternatively, you can print to stderr instead of stdout. In constrast to stdout, the stream stderr is unbuffered by default, so that it does not have this problem.
You can test whether my suspicion is correct by changing the line
printf("File cannot be opened.");
to
printf("File cannot be opened.");
fflush( stdout );
or to:
fprintf( stderr, "File cannot be opened." );
If the error message now gets printed, then this probably means that my suspicion was correct.
In any case, I recommend that you change the lines
if (NULL == f) {
printf("File cannot be opened.");
}
to the following:
if (NULL == f) {
fprintf( stderr, "File cannot be opened." );
exit( EXIT_FAILURE );
}
That way, the program will exit immediately if an occur occurs, instead of continuing execution.
Please note that the code posted above requires you to #include <stdlib.h>.
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.
My c code is
size_t n=0;
char *str = (char *)malloc(sizeof(char)* 1000)
FILE *fp = popen(" cat /conf/a.txt" ,"r" );
// my program comes in this function only if /conf/a.txt exists
getline(&str, &n, fp); <== crash if fp is null
My debugger shows that sometimes i get fp as null and hence my program crashes at line 6 . Sometimes i get valid pointere and it passes .
What is it , that controls this behaviour . I can't find problem in above code . Some help is appreciated .
I know I can have a check of fp==null but that is not my question . I just want to know , knowing that file is definitely present why is fp coming as null in some scenarios .
man of popen says The popen() function returns NULL if the fork(2) or pipe(2) calls fail, or if it cannot allocate memory.
i checked after crash and system is having enough memory ..
strerror and errno are your friends.
Example from the C++ references linked:
/* strerror example : error list */
#include <stdio.h>
#include <string.h>
#include <errno.h>
int main ()
{
FILE * pFile;
pFile = fopen ("unexist.ent","r");
if (pFile == NULL)
printf ("Error opening file unexist.ent: %s\n",strerror(errno));
return 0;
}
Example output:
Error opening file unexist.ent: No such file or directory
Using this method of checking errno after a failure will allow you to better diagnose your issue as it will print a more specific error message. There are many reasons a file can't be opened: no permission, bad path, file is locked from another process, IO errors during reading, etc. Ultimately your question seems to be asking why the open failed. Using these tools will answer that for you.
Update For Tag Change:
I've referenced and linked to C++ resources, but sterror and errno are both available in C as well by including errno.h.
popen() also fails if too many file handles are open in one process. I had one case in a server app, that was scanning one directory periodically for files.There was one scenario were no fclose call was made. So after some hours we reached the limit of 1024 open file handles on from that moment consecutive popen() calls would fail.
You can use ps -aux | grep {PROC_NAME} to retrieve the process id.
Then use sudo ls -l /proc/{PROC_ID}/fd to see the list of open file descriptors.
The program always ends up exiting. I seem to be running in to this problem frequently and I think I somehow previously fixed it but I'm not sure how. Why does it not create a file?
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
int main (void){
FILE *fp;
int c;
char file_w[100];
char string[100];
printf("Enter filename\n");
fgets(file_w, 100, stdin);
fp = fopen(file_w, "w");
if (fp == NULL){
printf("Can't open file\n");
exit(0);
}
printf("Enter a string");
fgets(string, 100, stdin);
for(c = 0; c <= sizeof(string); c++)
{
fprintf(fp, "%s\n", string);
}
printf("file written");
fclose(fp);
return 0;
}
Try to print the name of the file you have entered:
printf("%s\n", file_w);
just after the line you get file_w, just to be sure to enter what you want. I same cases the terminal could be wrongly configured.
Try to enter an absolute name path, if your computer is a Linux or Unix:
/tmp/newfile.txt
If your computer is Windows... Well try to see if C:\temp\ exist (or create it) and then enter:
C:\temp\newfile.txt
In any case, remember that you can specify an absolute path, and not only the file name. So double check if you have the rights (i.e. the permissions) to write into the directory where the file should be written.
In case you want check the error and have a better description of the problem try to use the following lines instead of your code, just under the fopen
if( fp == NULL ) {
// Error, as expected.
perror( "Error opening file" );
printf( "Error code opening file: %d\n", errno );
printf( "Error opening file: %s\n", strerror( errno ) );
exit(-1);
}
strerror it is a wonderful function just because return you a description of the problem instead of an error code.
I bet the problem is "invisible character after actual name from fgets()". I'll let you figure out exactly what that character is, where it comes from and how to fix it, as "struggling to solve a problem" is part of the learning process when it comes to programming. If it was easy, everyone could do it.
If the return value of fopen is NULL it means some error occurred. I suggest you look into the errno global to see what error has occurred to help you debug why it's not opening the file.
The w flag does the following:
write: Create an empty file for output operations. If a file with the same name already exists, its contents are discarded and the file is treated as a new empty file.
So it should create a file when none exists, or when it does exist, overwrite its content.
If it does not do that, you have another problem, but from the little information you've given, it's hard to tell what it is.
I tried as a name of file the following:
C:\\temp\\test_file.txt
or
fopen("C:\\temp\\employees.txt", "w");
and it works fine, without errors (I made it in Windows 10. GCC win32, Version: 6.3.0).
I think that you have to use an absolute path to create the file.
use gets() instead of fgets()...it will work
.
.
gets(file_w);
.
.
In my software I have to read multiple txt databases in a serial way, so I read the first, then I do something with the info I got from that file, than I open another one to write and so on.
Sometimes I got an error on an opening OR creation of a file, and then I got errors on all the following opening/creation, which uses different functions, different variables, different files.
So for example I call the function below, which uses two files, and I got an error "* error while opening file -%s- ..\n", then all the other fopen() in my code goes wrong!
This is an example of code for one single file:
FILE *filea;
if((filea=fopen(databaseTmp, "rb"))==NULL) {
printf("* error while opening file -%s- ..\n",databaseTmp);
fclose (filea);
printf("---------- createDatabaseBackup ----------\n");
return -1;
}
int emptyFolder=1;
FILE *fileb;
if((fileb=fopen(databaseBackup, "ab"))==NULL) {
printf("* error while opening file -%s- ..\n",databaseBackup);
fclose (fileb);
printf("---------- createDatabaseBackup ----------\n");
return -1;
}
else {
int i=0;
char c[500]="";
for (i=0;fgets(c,500,filea);i++) {
fprintf(fileb,"%s",c);
emptyFolder=0;
}
}
fclose(fileb);
fclose(filea);
There is an upper limit on the number of open handles for a given process. May be you have a handle leak in your program ?
Error while creating a file typically means you don't have access permission to the parent folder .
Those error log messages belong to your program . You can enhance it further. There is an errnum set by the os as fopen is essentially a system call. You can print that error number and get more info about your issue.
If fopen returned NULL, the file wasn't opened, so there's no point in trying to fclose it.
You should check the return value of fgets besides whether it is 0 or not. If it reads 500 characters and the buffer is not null-terminated, the fprintf will attempt to write more characters than is allocated for c