Open file in C linux - c

I am using C to open a file for reading. I have this code :
fp = fopen("./settings.cfg","r");
if (fp != NULL)
printf("OK");
else
printf("ERROR");
but I always get an error.
The file is located in the folder where the executable resides. I have tried writing only "settings.cfg". What might be the problem?

Try perror() to have the library itself tell you what, if anything, is wrong.
fp = fopen("./settings.cfg", "r");
if (fp != NULL)
printf("OK\n");
else perror("fopen");

You are opening the file in the "current directory", not "in the folder where the executable is".
In fact, unix has no easy way to find that particular folder; in Linux you could readlink() the /proc/[your pid]/exe link to find the executable and strip off the filename portion -- that will work in many cases, but there are some fringe cases like hardlinks that will make it fail.

From which directory do you run the program? It won't have the directory where it resides as the current directory, it will be inherited from the environment.
Could also be rights, that the file is owned by someone else and you don't have read rights.
Also double-check the filename. This sounds obvious, but do it anyway.

If file you are trying to open is in the same directory of your C compiled file, you must simply do
fp = fopen("settings.cfg","r");
if (fp != NULL)
printf("OK");
else
printf("ERROR");
without the initial " ./ " at the file's name

Related

Why doesn't fopen open existing file? (returns NULL, errno ENOENT)

I have posted this to document my issue, see my self-answer below.
No matter what I try, fopen(...) cannot open the existing file at the path which exists and returns NULL. I am executing the program from a bash script in ~/path. The program file is stored at ~/path/to.
int main(void) {
const char* filename = "my/file"
FILE* fp = NULL;
fp = fopen(filename, "r"); // file is still NULL, segfaults on indirection
if (!fp) exit(1);
fclose(fp);
}
fopen(3) is documented as capable of failing:
Otherwise, NULL is returned and errno is set to indicate the error.
So you should at least code:
FILE* fp = fopen(filename, "r");
if (fp == NULL) { perror(filename); exit(EXIT_FAILURE); };
and fopen won't even try to create a file that you open for reading only.
As a rule of thumb, you always need to check against failure of fopen (a minima like above), and report to your user (with the help of errno(3), perror(3), strerror(3) -used as strerror(errno)- ...) the reason of that failure. An educated user would be able to manage (perhaps with help from his sysadmin).
ENOENT is documented in errno(3) to mean
ENOENT No such file or directory (POSIX.1-2001).
Typically, this error results when a specified path‐
name does not exist, or one of the components in the
directory prefix of a pathname does not exist, or the
specified pathname is a dangling symbolic link.
I find that explanation pretty clear. In your case, you probably don't have any path/ directory in your current working directory, or you do have path/to/my/ directory without any file entry, etc (e.g. path/ exists but without to/ inside it) ....
You could improve your program by showing not only the errno (using strerror(errno) or perror) but also the working directory. See getcwd(3). Or you could leave your user to guess it. Your user could have changed the working directory, e.g. with a cd builtin command of his unix shell.

Accessing a different drive in c

I want to scan a directory, checking for JPEG-files (i.e. the combination of the first few bytes) and copying them to another drive. I successfully tested that program and it screens documents. However, I cannot access a whole directory (e.g. my accidentally erased SD-Card in D:/).
Here is how I tried to access it:
// remember the path from the command line
char *path = argv[1];
// open the path (preferably "D:\" - which is my SD-Card ;))
FILE *inptr = fopen(path, "r");
if (inptr == NULL)
{
fprintf(stderr, "inputfile could not be read\n");
return 1;
}
The output is "inputfile could not be read" - which is why I am quite confident that the error is right there. Do I need to address a directory differently? E.g. by using a pointer to the first bit of the drive?
I am a beginner - so please be gentle while laughing. ;)
Thank you very much!
Marcel
'fopen()' cannot open an entire directory or drive, it can only open a specific path. However, there are ways to accomplish the task of listing all files in a directory. This answer already contains some pertinent information.
Since you can already open files,you could adapt the loop shown there to perform the operation.
while ((dir = readdir(d)) != NULL)
{
printf("%s\n", dir->d_name);
if (/*Check whether file has the .jpg extension or another test*/)
{
// perform your copy operation on the file
}
}

Can't read or write using fopen in windows 7 because of permissions

I've been searching for a while to find this answer but I can't find a solution. Basically I'm trying to read and write to files in the c drive of my computer. However because it is windows 7 it chooses to be a pain in the back side and not give permission to my C program to do it. I have tried running it in administrator mode as well as trying to use different directories.
When the following code is run:
FILE *fp = fopen(strIn, "r");
if(fopen(strIn, "r") == NULL)
{
printf("Error: %d (%s)\n", errno, strerror(errno));
getchar();
}
The returning error is "Error 13 permission is denied". I know that Microsoft don't really like using fopen any more as it favours fopen_s but I find difficulty in understanding how to implement it and there is a lack of resources on it as well. Is there any way around this problem as it is really setting me back at the moment. Much appreciated,
Jack
Your code is opening the file twice:
FILE *fp = fopen(strIn, "r");
if(fopen(strIn, "r") == NULL) /* Second open, leaks FILE *! */
This might cause errors, since Windows can be picky about allowing a file to be opened multiple times. The second line should read:
if(fp == NULL)

open file dir problem

I'm running an Linux OS and trying to open file in C compiler like this :
file = fopen ("list.txt", "r");
but the file is not opend!
and when i put the full path like this :
file = fopen ("/home/rami/Desktop/netfilter/list.txt", "r");
it is working!
why the first example is not working?
the list.txt is in the same directory of the c file
thanks.
It's not the directory of the C file that matters, it's your current working directory that does. Try
cd /home/rami/Desktop/netfilter
before running the executable.
Do you know WHY the file didn't open?
Always check the return value of fopen() (and most other functions) and report back a readable error.
file = fopen("file.txt", "r");
if (!file) {
perror("file open");
exit(EXIT_FAILURE);
}
I see you've already found out what your problem is, but the above is a suggestion for the future (and to change your current project)
Is the executable also in the same dir as that of list.txt?
Edit: Actually that doesnt matter. It's the current working dir as per the other answer.

How to open a text file that's not in the same folder?

Since C it's not a language I am used to program with, I don't know how to do this.
I have a project folder where I have all the .c and .h files and a conf folder under which there is a config.txt file to read. How can I open that?
FILE* fp = fopen("/conf/config.txt", "r");
if (fp != NULL)
{
//do stuff
}
else
printf("couldn't open file\n");
I keep getting the error message. Why?
Btw, this only have to work on windows, not linux.
Thanks.
The easy way is to use an absolute path...
my_file = fopen("/path/to/my/file.txt", "r");
Or you can use a relative path. If your executable is in /home/me/bin and your txt file is in /home/me/doc, then your relative path might be something like
my_file = fopen("../doc/my_file.txt", "r");
The important thing to remember in relative paths is that it is relative to the current working directory when the executable is run. So if you used the above relative path, but you were in your /tmp directory and you ran /home/me/bin/myprog, it would try to open /tmp/../doc/my_file.txt (or /doc/my_file.txt) which would probably not exist.
The more robust option would be to take the path to the file as an argument to the program, and pass that as the first argument to fopen. The simplest example would be to just use argv[1] from main's parameters, i.e.
int main(int argc, char **argv)
{
FILE *my_file = fopen(argv[1], "r");
/* ... */
return 0;
}
Of course, you'll want to put in error checking to verify that argc > 2, etc.
You're probably going to want to look into the dirent family of routines for directory traversal.
The location of your .c and .h files is not really the issue; the issue is the current working directory when you run your executable.
Can you not pass in the full path to the fopen() function?

Resources