Never used fwrite(), so I'm not sure exactly what I'm doing wrong. I'm just testing it now and all I want to do is try to write a single char out to a file until it reaches the end. The file I'm writing to is one I downloaded from my teacher's website. When I check the properties of it, the type is only listed as "file". It's supposed to just be an empty 2MB file for us to write our code to (file system lab if anyone's wondering). Here's my code:
#include <stdio.h>
#include <string.h>
int main()
{
char c;
FILE *fp;
char testing[2] = {'c'};
fp = fopen("Drive2MB", "rw");
fseek(fp, 0, SEEK_SET); //make sure pointers at beginning of file
while((c=fgetc(fp))!=EOF)
{
fwrite(testing, 1, sizeof(testing), fp);
fseek(fp, 1, SEEK_CUR); //increment pointer 1 byte
}
fclose(fp);
}
When I run this, an error message pops up saying "Debug Assertion Failed!...Expression:("Invalid file open mode",0) and prints "The program '[3896] filesystem.exe: Native' has exited with code 3 (0x3)."
You have opened the file for reading (that's what the r stands for in fopen("Drive2MB", "r");). You may not write to a file opened for reading.
You're opening it in read only mode
Use r+ for the fopen
fp = fopen("Drive2MB", "r")
your openning your file in read only
try
fp = fopen("Drive2MB", "r+");
You've opened the file for reading with the "r" part of fopen. To write to the file, you can open it in read/write mode or write mode.
// Read/write mode
fp = fopen("Drive2MB", "r+");
// Write only mode
fp = fopen("Drive2MB", "w");
I never like to use "rw" personally. When you open a file, it really should have one reason to be opened. You also do not need to call fseek to move to the start of the file and you do not need to use fseek to advance the file pointer. fopen will automatically open it to the start of the file and fwrite will automatically advance the pointer. fseek should only be used if you are "seek"ing inside of the file to get to a specific point.
In the case you've given, you would only need write ("w") mode since you are not ever reading from the file.
Use fopen r+ or w+ to open the file.
Use fflush to flush data to disk after fwrite is complete.
Use ferror to check if there is any problem with the file stream after fwrite is complete.
Check whether the disk has enough free space.
I solved the problem with 3, 4.
Related
I'm trying to read the contents of "Danfilez.txt" using fgets. However on completion the program returns a random value and i'm unsure why. I'm new to programming so any help would be greatly appreciated!
int main()
{
FILE* Danfile = fopen ("Danfilez.txt", "w");
char fileinfo [50];// Character arrays for file data //
if (Danfile == NULL)
{
printf ("ERROR\n");
}
else
{
printf("Everything works!\n");
fprintf (Danfile, "Welcome to Dan's file.");
fgets(fileinfo,50,Danfile);
printf("%s\n",fileinfo);
fclose (Danfile); // CLOSES FILE //
}
return 0;
}
Since you're both reading and writing from the file you want to use "w+" to open the file rather than just "w".
But that won't fix things because once you've written out that text, your position in the file is still at the end, so you'll also need to reset the position before you can read anything in using fseek()
fseek(Danfile,0,SEEK_SET);
While using fopen() you pass the option for opening as an argument to the funtion. Here is the list:
"r" - Opens the file for reading. The file must exist.
"w" - Creates an empty file for writing. If a file with the same name already exists,
its content is erased and the file is considered as a new empty file.
"a" - Appends to a file. Writing operations, append data at the end of the
file. The file is created if it does not exist.
"r+" - Opens a file to update both reading and writing. The file must exist.
"w+" - Creates an empty file for both reading and writing.
"a+" - Opens a file for reading and appending.
Try using "r+" or "w+". After writing some text, your position in the file will move forward along with the text. Use rewind(FILE* filename) to move your position straight to the start of the file. For more information related to file handling i recommend checking what is inside stdio library:
https://www.tutorialspoint.com/c_standard_library/stdio_h.htm
I want to open a file, read its contents, and then append a line to the file. I thought I should use the "a+" flag for the task.
I have a function which opens a file and returns a pointer to this file.
FILE* open_weekly_disk_file(char* filename){
FILE* weekly_log;
weekly_log = fopen(filename, "a+");
//weekly_log = fopen(filename, "r");
if(! weekly_log){
printf("The attempt to open the weekly log failed!\n");
return NULL;
} else{
return weekly_log;
}
}
Then I have a function which calls the function above and uses scanf to read contents from the file:
void sample_function(char* filename){
FILE* log;
char token[100], current_read[100];
int limit;
log = opened_weekly_disk_file(filename);
// The problem happens here
for(limit=0; limit < TOKEN_NUMBER; limit++){
if(fscanf(log, "%s%s", &token, ¤t_read) == 2){
printf("%s %s\n", token, current_read);
}
}
...
}
This code works when I use:
weekly_log = fopen(filename, "r");
But does not work when I change the "r" flag to "a+". I get a Segmentation fault right before the for loop.
That is because the mode spec "a" opens a file for appending, with the file pointer at the end. If you try to read from here, there is no data since the file pointer is at EOF. You should open with "r+" for reading and writing. If you read the whole file before writing, then the file pointer will be correctly positioned to append when you write more data.
If this is not enough, please explore ftell() and fseek() functions.
from this SO QA
from the man page:
a+
Open for reading and appending (writing at end of file). The file is
created if it does not exist. The initial file position for reading is
at the beginning of the file, but output is always appended to the end
of the file.
Answer:
There is just one pointer which initially is at the start of the file
but when a write operation is attempted it is moved to the end of the
file. You can reposition it using fseek or rewind anywhere in the file
for reading, but writing operations will move it back to the end of
file.
So, the problem is not the fact that the file is opened in append mode, because it is not, as far as reading from it is concerned.
The problem lies in what your code does in those three dots
log = opened_weekly_disk_file(filename);
...
The code quite probably writes to the file, making the file cursor move to the end of it before the reading occurs.
The code snippet has an EOF after the while loop, the file has to be reopened again afterwards - fopen is reused. My question is if there is a way to avoid this clumsy double usage of fopen or not to use EOF in some way?
if (!(f=fopen("D:\\C\\Test.txt", "r")))
{
printf("File not existing\n");
}
while ((next=fgetc(f))!=EOF){
if (next=='1') num++;
}
printf("%d\n", num);
f=fopen("D:\\C\\Test.txt", "r");
while (fgets(buf, 1000, f)!=NULL)
printf("%s", buf);
Hope I was clear enough.
First, you should fclose() before reopening, if you do the reopen. If you don't, you are 'leaking' computer resources — you have an open file stream that you can't access.
Second, you can fseek() to the start of the file, or you can rewind() the file, without needing to reopen the file:
fseek(f, 0L, SEEK_SET);
rewind(f);
You should also note that your code as shown reports that it failed to open the file on the first time, but proceeds to use the file just as if it had succeeded. This is unlikely to lead to happiness. You should also check the success of the second open (if you do the reopen). Just because the file was there a second ago doesn't mean it is still there (though the chance of failure is slight, I grant you).
Use rewind(f) function.
It reset file pointer back to head, so after rewind() file as same as after 1st fopen().
For details, see: http://linux.die.net/man/3/rewind
a) fseek to the beginning
or
b) Close the file before reopening
So, I have this function on my program that is supposed to save a "car_str" structure into the desired place on a file specified as a parameter. But when I run it, it keeps overwriting the first slot again and again, as if fseek didn't point to the specified place on the file. Is there any problem with my code? I think it may be related with the multiplication, since without it the program does well, but I cannot point to the place I want.
void save(int car_nbr)
{
FILE *f;
f = fopen("memory.txt","wb");
if (!f)
{
printf ("error");
}
else
{
car_nbr--;
fseek(f, sizeof(struct car_str)*car_nbr, SEEK_SET);
fwrite(&car,sizeof(struct car_str),1,f);
rewind(f);
fclose(f);
printf("\nsaved");
}
}
you need to fopen with r+b.
if you fail than file not exist, so you can try use "wb"
"w" - 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.
"r+" - read/update: Open a file for update (both for input and output). The file must exist.
f = fopen("memory.txt","r+b");
I wish to open a file using the "a+b" mode, i.e. if it does not exist it is created automatically, but if it does I don't want to overwrite it. I want to be able to read and write to the file.
The file is binary, and I want to save records of a specific struct in it. So I want to do fseek() to the record I want and then save the record using fwrite().
The code looks as follows (MyRecord is a typedef to a struct, while FILENAME is a #define to the file's name):
int saveRecord(MyRecord *pRecord, int pos)
{
FILE* file = fopen(FILENAME, "a+b");
if (file == NULL)
{
printf("Unable to open file %s\n", FILENAME);
return 0;
}
fseek(file, pos * sizeof(MyRecord), SEEK_SET);
fwrite(pRecord, sizeof(MyRecord), 1, file);
fclose(file);
return 1;
}
However this code just appends the record to the end of the file, even if I set pos to 0. Why isn't fseek() with SEEK_SET working in append mode?
I know I can simply open it with "r+b" and if it fails open it with "wb", but I want to know why this doesn't work and why fseek() with SEEK_SET is leaving the file pointer at the end. Any references to places where this behaviour is documented appreciated (because I couldn't find any, or I am using the wrong keywords).
That's because in a mode, writing to the FILE* always appends to the end. fseek only sets the read pointer in this mode. This is documented in the C standard, 7.19.5.3 fopen:
Opening a file with append mode ('a' as the first character in the mode argument)
causes all subsequent writes to the file to be forced to the then current end-of-file,
regardless of intervening calls to the fseek function.
Plain C does not have any sane way to achieve what you want. If you're on a POSIX system or anything remotely close, you can use fd=open(FILENAME, O_CREAT|O_RDRW, 0666) and then fdopen(fd, "rb+").
Edit: Another thing you could try, with plain C:
f = fopen(FILENAME, "a+b");
if (!f) /* ... */
tmp = freopen(0, "r+b", f);
if (tmp) f = tmp;
else /* ... */
Use "r+b" mode and fallback to "w+b" if it fails.
The "a+b" mode, allows you to read and append; the "r+b" allows random read and write.
The documentation for fopen describes how the file behaves with the different modes.