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

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.

Related

How to paste a DIC file without deleting the default file or overwriting existing content with Go?

I want to check the characters of a file sequentially from the beginning of the file and if a character exists in file1 and not in file2, It appends the character.
Actually I have a DIC file that I want to install on the user's computer. But I don't want existing texts to be overwritten. Also, I don't want to delete the default file on the user's computer.
This DIC file is a screen reader dictionary used for the blind.
I would be grateful if you could help me
I wrote a code that checks the character, but I couldn't write it to the file.
This is my code: https://go.dev/play/p/4ogdlQaBRHz
Note: This code may be a incorrect code.

Opening a file in C in write mode

I am writing a C program that converts a text file into a binary file and vice versa. The first question I have is about opening a file in "w" mode. Is there any need to have a check that the output file is opened correctly?
FILE *output;
output = fopen("output.bin", "w");
if(output == NULL)
{ printf("Error opening output file\n");}
Basically my question is whether or not output would ever actually == NULL. Because if there was a problem opening the output wouldn't it just create a new file named "output.bin"?
Also my other question is how characters are actually saved in a binary file. I know I'm supposed to save each character as an unsigned char so it can have values between 0 and 255 and then I should write that char to the output file. The actual logical path of how that happens is not making sense if anyone can help me or point me in the right direction I would appreciate it!
Yes, opening a file in write mode might still fail. Here's a bunch of possible reasons, but certainly not the only ones:
You don't have permission to create or change the file.
The file is read-only, or the directory it would be in is read-only.
The file would be inside another file. (test/foo if test is a file and not a directory)
The filesystem is out of space or inodes (on filesystems that have a fixed number of inodes)
The user has hit their disk space quota.
The file would be on another computer, and the network is down.
The filename is invalid - such as C:/???*\\\\foo on windows.
The filename is too long.

Program to compile files in a directory in openedge

Could someone help me in writing a program that has to compile all the files in the directory and report error, if any. For which my program has to get the list of all files under the folder with its full path and store it in a temp-table and then it has to loop through the temp table and compile the files.
Below is a very rough start.
Look for more info around the COMPILE statement and the COMPILER system handle in the online help (F1).
Be aware that compiling requires you to have a developer license installed. Without it the COMPILE statement will fail.
DEFINE VARIABLE cDir AS CHARACTER NO-UNDO.
DEFINE VARIABLE cFile AS CHARACTER NO-UNDO FORMAT "x(30)".
ASSIGN
cDir = "c:\temp\".
INPUT FROM OS-DIR(cDir).
REPEAT:
IMPORT cFile.
IF cFile MATCHES "*..p" THEN DO:
COMPILE VALUE(cDir + cFile) SAVE NO-ERROR.
IF COMPILER:ERROR THEN DO:
DISPLAY
cFile
COMPILER:GET-MESSAGE(1) FORMAT "x(60)"
WITH FRAME frame1 WIDTH 300 20 DOWN.
END.
END.
END.
INPUT CLOSE.
Since the comment wouldn't let me paste this much into it... using INPUT FROM OS-DIR returns all of the files and directories under a directory. You can use this information to keep going down the directory tree to find all sub directories
OS-DIR documentation:
Sometimes, rather than reading the contents of a file, you want to read a list of the files in a directory. You can use the OS–DIR option of the INPUT FROM statement for this purpose.
Each line read from OS–DIR contains three values:
*The simple (base) name of the file.
*The full pathname of the file.
*A string value containing one or more attribute characters. These characters indicate the type of the file and its status.
Every file has one of the following attribute characters:
*F — Regular file or FIFO pipe
*D — Directory
*S — Special device
*X — Unknown file type
In addition, the attribute string for each file might contain one or more of the following attribute characters:
*H — Hidden file
*L — Symbolic link
*P — Pipe file
The tokens are returned in the standard ABL format that can be read by the IMPORT or SET statements.

Open file in a different directory

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);

Search a pattern in .gz file in C

I want to read a .gz file (text.gz) with 300MB length and search a pattern in it. I opened the text file in a binary format using fopen with "rb" and stored it in a buffer. When I search a pattern that I know it exists in the text, the result is wrong. When I debug the program, the elements of the buffer are different from what I expect. Do I have to read and store these kind of files in other ways??????
You might try using zlib and gzread to read the file.
http://zlib.net/manual.html
Try this.
gunzip -c file.gz | grep <pattern>
If the program is exiting and failing to read the file, a real common problem is that you don't close the file in Notepad or whatever is using it and the FileIO fails due to not being able to access the file. Make sure you don't have anything with that file open before you test your program.

Resources