So the pseudo code is:
FIle existing = Read whole content of file.
String newcontent = "Blah Blah This is first line" + existing
f.write(newcontent);
The actual code is
void Prepend(char *string, char *file_name)
{
char buf[100];
FILE *fp1, *fp2;
Append(string, "temp_file");
fp1 = fopen(file_name, "a+");
fp2 = fopen("temp_file", "a+");
if (!fp1 && !fp2) {
printf("Unable to open/"
"detect file(s)\n");
exit(1);
}
fprintf(fp2, "\n");
while (!feof(fp1)) {
fgets(buf, sizeof(buf), fp1);
}
rewind(fp2);
while (!feof(fp2)) {
fgets(buf, sizeof(buf), fp2);
}
fclose(fp1);
fclose(fp2);
remove(temp_file);
}
/*-----------------------------------------------------------------------------*/
void Append(char *string, char *file_name)
{
FILE *file = fopen(file_name, "a");
if(file==NULL)
{
printf("Error opening file.");
}
else
{
fputs(string, file);
}
fclose(file);
}
I know there is a way with fseek
maybe and other pointer related stuff, but I thought it would be better and faster for me to go with the "easy way" and just make a new temp file and delete it right afterwards.
Well, it also doesn't work.
since you're using a temporary file, a secondary buffer should not be required, just append the text, then move the old file contents into the new one.
A few things you should lookout for,
if (!fp1 && !fp2)
is only true if both files failed to be opened ,its better to check the results individually so we know where we failed. You could have replaced &&
with ||
but it will be ambiguous why it failed unless you re-check the file pointer values.fp1
into fp2
I only see calls to fgets()
, you read fp1
into buf
then you read fp2
into buf
, doing nothing with the data both times. If the files are larger than 100 bytes you'll end up with the last 100 or less bytes of data being stored in buf.A short example of a method that should work, with error checking (not necessarily the best error checking but gives you an idea where errors can occur):
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <string.h>
int Prepend(char *string, char *file_name)
{
FILE *fp1 = NULL, *fp2 = NULL;
struct stat fs;
if (stat("temp_file", &fs) == 0) {
printf("Error, there is already a file named \"temp_file\" in the current working directory\n");
return -1;
}
if ((fp1 = fopen(file_name, "r")) == NULL) {
printf("Error : %s\n", strerror(errno));
printf("Failed to Open file %s\n", file_name);
return -1;
}
if ((fp2 = fopen("temp_file", "w")) == NULL {
printf("Error : %s\n", strerror(errno));
printf("Unable to create Temporary file\n");
fclose(fp1);
return -1;
}
if (fputs("Prepended String\n", fp2) == EOF) {
printf("Failed to write string to file\n");
fclose(fp1);
fclose(fp2);
if (remove("temp_file") != 0)
printf("Error : %s, while removing temp_file\n", strerror(errno));
return -1;
}
int c;
while((c = fgetc(fp1)) != EOF) {
if(fputc(c, fp2) == EOF) {
printf("Error while transfering data from %s to %s\n", file_name, "temp_file");
fclose(fp1);
fclose(fp2);
if (remove("temp_file") != 0)
printf("Error : %s, while removing temp_file\n", strerror(errno));
return -1;
}
}
fclose(fp1);
if (remove(file_name) != 0) {
printf("Error : %s, while removing %s\n", strerror(errno), file_name);
fclose(fp2);
return -1;
}
fclose(fp2);
if (rename("temp_file", file_name) != 0) {
printf("Error : %s, while renaming temp_file\n", strerror(errno));
return -1;
}
return 0;
}
fclose()
can also return EOF on error and errno is set to indicate the error. However, any further access (including another call to fclose()) to the stream results in undefined behavior. so you can print the error but there isn't much you can do about it.