Open file in a different directory - c

I have to do a simple task. I have to open a file which is in a directory. I have the .c file in src, when I compile I move the programs (a.out) in the a bin directory. I want to read a file in the directory asset. All these folders are in a main folder.
If I do this
FILE* fp = fopen("../asset/team_list", "r");
it won't open the file. Why can't I open the file in that directory?

guess you forgot to put the extension of your file
FILE* fp = fopen("../asset/team_list.doc", "r");

Find what error you get using perror/explicit mention of error message and expect a possible reply from stackoverflow.
Make sure you are pointing out to the correct directory where the file is present from the PWD from where your program is being executed.

Relative paths are relative to the current working directory of the process, which might not be the same location as the binary file. So, if you are in /home/user/ and you run ./project/bins/my.exe then your current working directory is /home/user/, relative paths need to be relative to that location.
You can try a few things to help with this issue. First, after the failed open you could examine errno to see why the open failed, is it permissions, invalid path?
Alternatively you might have access to the strace program, this traces system calls, like open from your application, and will allow you to see the failed system call. Try strace ./project/bins/my.exe, you'll see a lot of output, dig through this looking for the failed open call, and try to figure out why this is failing, again the errno will be included in the trace to help understand the failure.
Lastly, you could just add a call to getcwd to your program and print the result (as a debugging aid), this places the current working directory into a buffer, something like this:
char buffer [PATH_MAX + 1];
getcwd (buffer, PATH_MAX + 1);
printf (buffer);

Related

Fopen - No such file or directory in C

This code does not open file properly, it returns no such file or directory, although the path and privilege are there and no other program is using the file. How can I fix the error? I tried swapping the path and moving the file, the error is there still.
char string[105];
FILE* file = fopen("C:\\Users\\Public\\Documents\\a.txt", "r");
while (fgets(string, 100, file)) {
printf("%s", string);
}
It can be surprisingly tricky to open a simple file! Lots of things can go wrong. I recommend writing slightly more verbose code, like this:
#include <string.h>
#include <errno.h>
char* filename = "C:\\Users\\Public\\Documents\\a.txt";
char string[105];
FILE* file = fopen(filename, "r");
if (file == NULL) {
fprintf(stderr, "can't open %s: %s\n", filename, strerror(errno));
exit(1);
}
while (fgets(string, 100, file)) {
printf("%s", string);
}
The point is that the error message prints out both the name of the file it tried but failed to open, and the actual reason it couldn't open it. (Also, by storing the filename in a variable, you make it absolutely certain that the filename it prints in the error message is the filename it tried but failed to open.) It sounds like you already know that the error was "no such file or directory", but I'm not sure how you know this.
Even though I've been programming in C for a long time, sometimes I still have this problem. One thing I'll sometimes do is use my mouse to copy the exact filename string printed in the error message, the file the program said it couldn't open, the file I'm sure is really there, and paste it into a terminal window (or CMD or Powershell if you're on Windows), along with a directory-listing command, to see if the operating system can actually see the file. That is, for your example, the command I'd run is
dir C:\Users\Public\Documents\a.txt
but the point is that I would not actually type the pathname "C:\Users\Public\Documents\a.txt", instead I would copy and paste it out of the error message that the program printed. Sometimes there are surprising little impossible-to-spot differences between the filename you thought it was trying to open, versus the filename it was actually trying to open, and this exercise is a good way to let the computer help you find those differences.
Remember, too, that you'll get the error "No such file or directory" if there's no file by that name in the directory, or if the directory isn't there at all. For example, if you're trying to open the path
C:\Users\Public\Documents\a.txt
and the file a.txt keeps not being there, and you keep checking your home directory
C:\Users\Donkey\Documents
and you keep seeing that the file is there, it can be surprisingly easy to overlook what the real problem is. :-)
Addendum: You might be having an issue with the different Unix/Linux versus Windows file path separators, that is, / versus \. Usually, on a Windows machine, it's safest to use \, as you've done. (One very frequent mistake is to forget to double the backslashes, but it looks like you got that right.) Depending on your programming environment, if there's some level of Unix emulation going on, you can sometimes use Unix-style /, and it will automatically translate to \ for you. I've never heard of a situation where using \ made it not work (which is a possibility being explored in the comments), but you might experiment with that, perhaps trying
char* filename = "/c/Users/Public/Documents/a.txt";
or (less likely)
char* filename = "C:/Users/Public/Documents/a.txt";

How to programatically move a Linux symlink to a different file system (copy) in C?

rename() C function does not work across file systems. So I can move files via a copy by opening them, reading them and writing them to a new copy and then unlinking. But I have a hard time getting this to work with symlinks. (The idea is to move a folder with a bunch of other files/folders/symlinks etc inside of it). Basically implementing a mv command in C.
open(file, O_RDONLY)
while ((c = read(source_descriptor, buf, SIZE)) > 0){
write(d, buf, c);
}
unlink file;
Works good for normal files (and I have another function handling directories without issues). But whenever it hits a symlink I get perror spitting out No such file or directory.
I can detect if its a symlink via d_type but am not sure how to read/copy it once I have one since the normal file copy doesnt seem to work with symlinks because open() refuses to open them.
Once you have determined that you're dealing with a symlink (which can be done e.g. by using lstat()), you can read its contents with readlink() and recreate it at the target location by calling symlink().
See also man 7 symlink.
When you open a symlink without the O_NOFOLLOW flag, it will dereference the symlink (or symlink chain, if it's a symlink to a symlink). If the destination does not exist, open will fail. The O_NOFOLLOW flag makes sure, that if you attempt to open a symlink you will realiably get an error.
To "copy" a symlink, you'll have to read it with readlink and create a new symlink at the destination. However you may have to adjust the path it points to.
However if a program of yours has the need to copy directory trees on a *nix system, the correct way to implement this is not to reinvent the wheel, but to follow the Unix way and just execute the cp program with the right arguments.

Where to put files so C program can access them?

I'm trying to open files in a C program, but I am unsure where to place the files I want to open (as in which directory). Here is the code, but I really just need to know where to place the file I want to open with fopen().
FILE *fileptr;
fileptr = fopen("QuizQuestions.txt", "r");
if (fileptr == NULL) {
printf("Unable to open file.");
}
Any help is appreciated!
If you don't use an absolute pathname in your code, paths are interpreted relative to the working directory of the user when they run the program. So for your program, the user should put the file in their current directory.
The location of the program itself is irrelevant. If you want to get the location of the program, you see this question:
How do I find the location of the executable in C?
You can then concatenate the directory with the filename.
You need to keep files where source code file is placed.Otherwise, you need to give absolute path.

fopen in C(Linux) returns "Too many open files"

static char filename[128] = "trace.txt";
g_file = fopen(filename, "w");
if(NULL == g_file)
{
printf("Cannot open file %s.error %s\n",filename,strerror(errno));
exit(1);
}
I am trying to open a empty text file named trace.txt in write mode (in my working directory.)
The program is creating an empty file trace.txt in my directory.but the check (NULL == g_file)
is returning true and it is returning error code 24 (Too many open files.).Any idea why this is.This is the first file I am opening in my program.
Surprisingly the code is creating an empty file in my working directory by the name specified.However the check for null file pointer is succeeding for some reason.? :(
You probably have a file descriptor leak.
If your code keeps opening files, never closing them, you will reach the limit sooner or later, and then fopen will fail.
You can check this by printing the file descriptor numbers you get whenever opening a file. If they keep growing, you have a leak.
It is most likely due to your system reaching its maximum allowed open file handles.
You can easily test this by running the following:
$ dd if=/dev/urandom of=test.dat bs=16 count=1
If you are out of file handles, this should provide the same or similar error.
You can trouble shoot this using some of the following commands:
To see the maximum allowed open files:
$ cat /proc/sys/fs/file-max
To see the which files are currently open (remember this includes device files, sockets, etc):
$ lsof
You can also use lsof to get a count of open files:
$ lsof | wc -l
This looks like a similar issue to what you're having, but I'm not entirely sure if it will help you solve the problem. Might be worth a look:
Problem with writing to file in C
Correct, I faced same error message and found that I was trying to close the file in a function but not where it was opened. So I then closed in the function where it was opened, later everything went fine.

fopen() returning a NULL pointer, but the file definitely exists

The code I have is as follows:
FILE *txt_file = fopen("data.txt", "r");
if (txt_file == NULL) {
perror("Can't open file");
}
The error message returned is:
Can't open file: No such file or directory
The file 'data.txt' definitely exists in the working directory (it exists in the directory that contains my .c and .h files), so why is fopen() is returning a NULL pointer?
Standard problem. Try
FILE *txt_file = fopen("C:\\SomeFolder\\data.txt", "r");
I.e. try opening it with the full absolute path first ; if it works then you just have to figure out what the current directory is with _getcwd() and then fix your relative path.
Is it possible that the filename is not really "data.txt"?
On Unix, filenames are really byte strings not character strings, and it is possible to create files with controls such as backspace in their names. I have seen cases in the past in which copy-pasting into terminals resulted in files with ordinary-looking names, but trying to open the filename that appears in a directory listing results in an error.
One way to tell for sure that the filenames really are what you think they are:
$ python
>>> import os
>>> os.listdir('.')
My problem was that I had a file filename.txt and I didn't realize that in reality it was filename.txt.txt due to windows not showing the extension.
Make sure that your input file is in the same directory as the executable, which may be different than the one where your source files are kept. If you're running the program in an IDE debugger, make sure that your working directory is set to the location of the input file. Also, if you're running in *nix rather than Windows, you may need to prepend a "./" to the input filename.
Invisible SPACE character in file name?
Once a year I have a similar problem:
I try to open a file with the filename in a string, obtained from a sting operation. When I print the name it seems OK, but fopen() returns a null pointer. The only help is printing the name with delimiters showing the exact beginning and end of the filename string. Of course this does not not help with unprintable chars.
I just had a similar issue like this where I knew the path was correct and the file was in the right location. Check the file permissions. It is possible that the program cannot access the file because it is getting permission denied.
I encountered the same errno to fopen on Linux from a script file corrupted by Windows.
ENOENT 2 No such file or directory
Wordpad on Windows (or some other Microsoft culprit) inserted CRLF = (0x0D, 0x0A) into my linux script files in place of newline = LF = 0x0A. When I read the file name into a buffer and called fopen if failed due to the invisible appended CR character.
In the Codelite editor on Linux Mint I was able to show EOL characters (View > Display EOL) and remove them with find and replace, using copy and paste of the CRLF from the corrupted script files and the LF from an uncorrupted file into the text fields.

Resources