I have a program that reads a file, returned from an OPENFILENAME. It has a large edit control. That is supposed to get the text from the file and let the user save it. I just cannot wrap my head around it. fopen(path, "r+") throws an exception for some odd reason.
Exact error message:
"Exception thrown at 0x00007FF87B5A86E2 (ucrtbased.dll) in Notepad (C).exe: 0xC0000005: Access violation reading location 0x000000000000722B."
Here is the function reading it:
void ReadOpenedFile(char* path, HWND hTextBox)
{
// Warning suppressor because it doesn't build without fopen_s it seems.
#pragma warning (disable: 4996)
FILE* f = fopen(path, 'r+');
SetWindowText(hTextBox, f);
fclose(f);
}
I had gotten it from the documents folder, but I knew because Windows protects it, I tried the music folder. It still didn't work. I tried many different websites. They all said the same approach to open files. I always get the same exception. I had tested the OPENFILENAME was returning the correct file path, and it does.
Any help is appreciated!
You never read the file but only open it. It should be (beware untested):
void ReadOpenedFile(char* path, HWND hTextBox)
{
// Warning suppressor because it doesn't build without fopen_s it seems.
#pragma warning (disable: 4996)
FILE* f = fopen(path, "rt");
// error test for f == NULL omitted for brievety
char buf[16384]; // adjust per you requirement up to ~32000
size_t sz = fread(buf, 1, sizeof(buf) - 1, f);
buf[sz] = '\0';
SetWindowTextA(hTextBox, buf);
fclose(f);
}
Related
I am trying to read a file which exists in my project folder. But when I want to get the string in it the file's data changes to (null) .
I tried both "w" and "r" but none of them worked.
Here is my code :
FILE* f;
if (!(f =fopen("a.txt", "r"))) {printf("Could not open file\n"); return;}
char s[10000];
fgets(s, 10000, f);
printf("%s", s);
Output:
(null)
Note : There is no error in opening the file.
here is the file after opening
Edit:
here is the full version of my code:
FILE* channelfile;
char filename[100] , name[]="hi";
sprintf(filename, "./Resources/Channels/%s.cyko", name);
if (!(channelfile =fopen("hi.cyko", "r"))) {printf("Could not open file\n"); return;}
char s[10000];
fgets(s, 10000, channelfile);
printf("%s", s);
cyko is my file type (it is not general)
The file contains the text (null), as shown by your screendump.
As a result, printing the contents of the file prints (null).
QED.
Since there are several people following this question, I will now inform them of the outcome:
After explaining how to use a debugger to the OP, he was able to find that the actual problem was not in the code he had posted, but rather in another part of his project.
He assumed that the code he posted was responsible for the problem, because he only experienced the problem after changing the code he posted. However, it seems that this change only triggered the bug; the bug itself was in another part of the program.
I'm trying to write to an existing bmp file.
the action should delete the data on it, which is fine by me.
first i want to read the original header, then switch the width and the height data and then "create" new file with the new header.
for some reason, i managed to open and read the file in "rb" mode, but when i try to do so in "wb" mode or any other mode for writing, the file pointer is initialized as NULL.
reading with struct BmpHeader works just fine.
Update:
after using:
err = fopens(...);
i got that err = 13.
how can i fix this?
#define HEADERSIZE 54
int **Matrix = GivenMatrix;
FILE *f;
int row, col,i;
BmpHeader header;
long Newwidth, Newheight;
int pixelBytesInRow, padding;
fopen_s(&f, "plate.bmp", "rb");
fread(&header, HEADERSIZE, 1, f);
fclose(f);
Newheight = header.width;
Newwidth = header.height;
header.width = Newwidth;
header.height = Newheight;
fopen_s(&f, "plate.bmp", "wb");
fwrite(&header, HEADERSIZE, 1, f);
fopen_s() returns a non-zero error code and sets the file handle to null and the global value errno to the appropriate error code when an error occurs. To see what happened, use perror() to print the error message:
if (fopen_s(&f, "plate.bmp", "wb") != 0) {
perror("could not open plate.bmp");
// Exit or return.
}
perror() will append the system's error to your own message, with a : before it.
Also do the same when opening the file for reading. Never assume that file operations are going to succeed. You really, really need to do error handling when doing any kind of I/O.
If the error is "permission denied", then that usually means the file is open elsewhere. Either in your own program, or by an external program (like an image viewer you're using to check the bmp file.) Close it. On Windows, you can't open files in write mode if they are open elsewhere too.
If you want to avoid situations where you forgot to close files, you should use RAII facilities in C++. It's arguably the most important and useful part of C++. In this case, you could either switch to C++ streams, or if you want to continue using the cstdio API, then wrap your file handles in your own type that automatically closes the handle when it goes out of scope (either in the destructor, or by using a unique_ptr with a the custom deleter set to fclose.)
I have this function
char* Readfiletobuffer(char* file, FILE* fp){
char * buffer;
int file_size;
fp = fopen(file, "r");
if (fp != NULL) {
fseek(fp, 0, SEEK_END);
file_size = ftell(fp);
buffer = (char*) malloc((file_size + 1) * sizeof(char));
fseek(fp, 0, SEEK_SET);
fread(buffer, file_size, 1, fp);
buffer[file_size] = '\0';
return buffer;
} else {
printf("error loading file");
}
fclose(fp);
}
which I call 1050 times in my program and at the 1019th time fopen() returns a NULL pointer.
It doesn't depend on the file, it's always the 1019th time so I think it's something with freeing memory but why isn't the fclose() call enough?
Does someone have an idea?
Your program can tell you with errno, the global variable where many functions assign their error code to when they fail. Combined with strerror to provide a human readable error message, you'd change your error handling to something like this.
#include <errno.h>
#include <string.h>
...
fp = fopen(file, "r");
if (fp == NULL) {
fprintf(stderr, "Could not open '%s': %s", file, strerror(errno));
exit(1);
}
fseek(fp, 0, SEEK_END);
file_size = ftell(fp);
...
Note the use of early exit to eliminate having nest the whole function in an if/else block.
Also note that you're failing to check the rest of your file operations. fseek, ftell, and fread can all fail. You need similar checks for all of them. Rather than littering your code with error handling, and probably forgetting to do it in a few places, I recommend writing little wrappers.
FILE *open_file(const char *filename, const char *mode) {
FILE *fp = fopen(filename, mode);
if( fp == NULL ) {
fprintf(
stderr, "Could not open '%s' for '%s': %s\n",
filename, mode, strerror(errno)
);
exit(1);
}
return fp;
}
Note that this isn't the best error handling, it simply exits on error. At this stage in your learning C, it's probably best to just bail out on an error. If you did something like return NULL odds are you won't have the error handling to handle a null pointer and it will just bounce around causing mysterious problems and crashes later in the code. For now it's best to halt and catch fire as close to the error as possible.
Spoiler alert: your process ran out of file handles because you're not closing your files. As #BLUEPIXY correctly points out in the comments your fclose is after you return normally and will only happen if the file fails to open.
Since you're passing in the file pointer, maybe you intend to use it later? In that case you can't hold onto that many open files and you'll have to redesign your code. If not, there's no reason to pass it in since the function is opening it.
You should have gotten a warning like this, if you had warnings turned on with -Wall.
test.c:23:1: warning: control may reach end of non-void function [-Wreturn-type]
}
If the file fails to open, nothing gets returned, and that's not ok.
Don't ignore your warnings, fix all of them. Investigating this warning would have pointed you at the problem.
Check all your file operations to make sure they succeeded.
Include strerror(errno) in your error messages so you know why it failed.
Investigate and fix all your warnings.
Apparently, there's no data regarding my question (I tried searching it out here but none of the threads I've read answered my doubt). Here it is: I'm trying desperately to figure out how can I put a correct path into the fprintf function and none of my tries have been successful. Here's the program:
#include <stdio.h>
#include <stdlib.h>
int main(){
FILE *fp = NULL;
//opening the file
fp = fopen("C:/Users/User1/Desktop/myfile.txt", "w+");
//if there's an error when opening the file, the program shuts down
if(fp == NULL){
printf("error");
exit(EXIT_FAILURE);
}
//print something on the file the program just opened (or created if not already existent)
fprintf(fp, "to C or not to C, that is the question");
//closing the file
fclose(fp);
//end of main function
return 0;
}
My question is: why my program always shuts down? What am I doing wrong? It's just a Windows problem (I saw that, on the User1 folder icon, there's a lock, could be a permission denied thing?) or I'm just putting the path in an incorrect way? I tried to use a string to save the path, I tried to change the opening mode, I even tried to disable all the antiviruses, antimalwares and firewalls I have installed on my computer but nothing, the program still doesn't create the file where I want it.
P.S. Sorry for bad English.
P.P.S. Sorry if a similar question has been already posted, I didn't manage to find it.
fp = fopen("C:\Users\User1\Desktop\myfile.txt", "w+");
The character \ is the escape character in C. You must escape it:
fp = fopen("C:\\Users\\User1\\Desktop\\myfile.txt", "w+");
Even better, windows now supports the / directory separator. So you can write:
fp = fopen("C:/Users/User1/Desktop/myfile.txt", "w+");
With no need to escape the path.
Reference:
MSDN fopen, specifically the Remaks section
Use perror() to have the Operating System help you determine the cause of failure.
#define FILENAME "C:/Users/User1/Desktop/myfile.txt"
fp = fopen(FILENAME, "w+");
// report and shut down on error
if (fp == NULL) {
perror(FILENAME);
exit(EXIT_FAILURE);
}
I am read from a file like this:
#include <stdio.h>
int main() {
FILE *fp = fopen("sorted_hits", "r+");
while(!feof(fp)) {
int item_read;
int *buffer = (int *)malloc(sizeof(int));
item_read = fread(buffer, sizeof(int), 1, fp);
if(item_read == 0) {
printf("at file %ld\n", ftell(fp));
perror("read error:");
}
}
}
This file is big and I got the "Bad file descriptor" error sometimes. "ftell" indicates that the file position stopped when error occurred.
I don't know why it is "sometimes", is that normal? does the problem lie in my code or in my hard disk? How to handle this?
perror prints whatever is in errno as a descriptive string. errno gets set to an error code whenever a system call has an error return. But, if a system call DOESN'T fail, errno doesn't get modified and will continue to contain whatever it contained before. Now if fread returns 0, that means that either there was an error OR you reached the end of the file. In the latter case, errno is not set and might contain any random garbage from before.
So in this case, the "Bad file descriptor" message you're getting probably just means there hasn't been an error at all. You should be checking ferror(fp) to see if an error has occurred.
You seem to be mixing text and binary modes when reading the file.
Normally when you use fread you read from a binary file i.e. fread reads a number of bytes matching the buffer size but you seem to be opening the file in text mode (r+). ftell doesn't work reliably on files opened in text mode because newlines are treated differently than other characters.
Open the file in binary mode (untranslated) instead:
FILE *fp = fopen("sorted_hits", "rb+");
If that's really what your loop looks like, my guess would be that you're probably getting a more or less spurious error because your process is just running out of memory because your loop is leaking it so badly (calling malloc every iteration of your loop, but no matching call to free anywhere).
It's also possible (but a lot less likely) that you're running into a little problem from your (common but nearly always incorrect) use of while (!feof(fp)).
Your all to printf also gives undefined behavior because you've mismatched the conversion and the type (though on many current systems it's irrelevant because long and int are the same size).
Fixing those may or may not remove the problem you've observed, but at least if you still see it, you'll have narrowed down the possibilities of what may be causing the problem.
int main() {
FILE *fp = fopen("sorted_hits", "r+");
int buffer;
while(0 != fread(&buffer, sizeof(int), 1, fp))
; // read file but ignore contents.
if (ferror(fp)) {
printf("At file: %ld\n", ftell(fp));
perror("read error: ");
}
}