open an existing file in buffer and write on it

R

Rudra Banerjee

Dear friends,
I write some data on a new or existing file as:
FILE *fop = fopen(filename, "a" );
if (!fop){
filename="Untitled.bib";
fop= fopen(filename,"a");
}
gtk_label_set_text(GTK_LABEL(flabel), filename);
g_fprintf( fop, "@%s{%s,\n", strcombo, strkey );
if( strlen(strAuth)!=0)
g_fprintf( fop, "\tAuthor=\"%s\",\n", strAuth);
if( strlen(strEditor)!=0)
g_fprintf( fop, "\tEditor=\"%s\",\n", strEditor);

and so on.
But it is better if I can do it in buffer and save it only when the buffer is filled up. Can anybody please show me the way?
NB: I am a fortran programmer, and a layman in C. So, I will be grateful if I have some elaborate answer.
 
J

James Kuyper

Dear friends,
I write some data on a new or existing file as:
FILE *fop = fopen(filename, "a" );
if (!fop){
filename="Untitled.bib";
fop= fopen(filename,"a");
}
gtk_label_set_text(GTK_LABEL(flabel), filename);
g_fprintf( fop, "@%s{%s,\n", strcombo, strkey );
if( strlen(strAuth)!=0)
g_fprintf( fop, "\tAuthor=\"%s\",\n", strAuth);
if( strlen(strEditor)!=0)
g_fprintf( fop, "\tEditor=\"%s\",\n", strEditor);

and so on.
But it is better if I can do it in buffer and save it only when the buffer is filled up. Can anybody please show me the way?
NB: I am a fortran programmer, and a layman in C. So, I will be grateful if I have some elaborate answer.

gtk_label_set_text() and g_fprintf() are not part of the C standard
library. If they're a part of some other library (as seems likely from
the names), you'll get better answers to your questions by directing
them to a forum associated with that library. If they're your own
functions, you should provide us with the definitions of those
functions, so we can better answer your question.

One key point: C standard library I/O is buffered by default, so if
g_fprintf() doesn't provide buffered I/O, you might want to consider
using fprintf() instead. If you want to gain some control over how the
buffering is done, you should use setbuf() or setvbuf(). You can change
the buffer size, and change between full buffering, line buffering, or
no buffering, and you can even allocate the space for the buffer yourself.
 
R

Rudra Banerjee

James,
thanks for your elaboration.
But, I have used fprintf instead of g_fprintf, which is, by defination, " An implementation of the standard fprintf() function which supports positional parameters, as specified in the Single Unix Specification."

Also, from http://www.gnu.org/software/libc/manual/html_node/Buffering-Concepts.html, I think fprintf is "unbuffered", as it reads/writes directly to the file.

What I am trying to achieve is read the whole file in buffer and edit the buffer only! The buffer will flush to file when that is filled....something in that way(guess I am too vague here)!
I was trying something like:
FILE *fopf = fopen(filename, "a" );
if (!fopf){
filename="Untitled.bib";
fopf= fopen(filename,"a");
}
char fop[]="Hello World";
int buf_size= strlen(fop)+1;
fwrite(fop,buf_size,1,fopf);
fclose(fopf);
if( strlen(strAuth)!=0)
g_fprintf( fop, "\tAuthor=\"%s\",\n", strAuth);

but that caused the app to crash, with Segmentation fault (core dumped) while writing to it.
 
R

Rudra Banerjee

gtk_label_set_text() and g_fprintf() are not part of the C standard

library.
James Kuyper

Yes, you are right. They are part of gtk and glib. But do you really think the problem is that library related? I guess its more to do with my understanding of C.
 
J

James Kuyper

James,
thanks for your elaboration.
But, I have used fprintf instead of g_fprintf, which is, by defination, " An implementation of the standard fprintf() function which supports positional parameters, as specified in the Single Unix Specification."

As such, questions about g_fprintf() are best answered in a
UNIX-oriented newsgroup, such as comp.programmer.UNIX.
Also, from http://www.gnu.org/software/libc/manual/html_node/Buffering-Concepts.html, I think fprintf is "unbuffered", as it reads/writes directly to the file.

Why would you think that? it says "Newly opened streams are normally
fully buffered, with one exception: a stream connected to an interactive
device such as a terminal is initially line buffered." A file is
unbuffered only if you explicitly call setvbuf() to make it unbuffered.
What I am trying to achieve is read the whole file in buffer and edit the buffer only! The buffer will flush to file when that is filled....something in that way(guess I am too vague here)!

The way to do that in C is to fread() into a buffer, edit the buffer,
and then fwrite() it.

The buffer you're editing will be different from the buffer associated
with the file, but copying between those buffers is not going to cost
you much time by comparison with the file I/O. You could avoid those
copies by making both the files unbuffered, but I would recommend that
approach only if you're going to have but a single fread() and a single
fwrite(). If there are multiple reads and writes you're better letting
the C standard library handle the I/O buffer, while you concentrate on
your internal data buffer.
I was trying something like:
FILE *fopf = fopen(filename, "a" );
if (!fopf){
filename="Untitled.bib";
fopf= fopen(filename,"a");

Note: you make no attempt to check whether the second fopen() failed.
It's quite possible for it to fail, and the behavior of your program is
undefined if it does.
}
char fop[]="Hello World";
int buf_size= strlen(fop)+1;
fwrite(fop,buf_size,1,fopf);
fclose(fopf);

You also failed to check whether fwrite() or fclose() failed. Because
fopf IS buffered, a failed fclose() implies that there might still be
data in the buffer which has not yet been written to the file.
if( strlen(strAuth)!=0)
g_fprintf( fop, "\tAuthor=\"%s\",\n", strAuth);

but that caused the app to crash, with Segmentation fault (core dumped) while writing to it.

I don't have documentation for g_fprintf(), but in your first message,
you passed it a FILE* as the first argument, and in this message, you're
passing a char*. One of the two is probably incorrect. Since this is the
one that failed, it's probably the incorrect one.
I think you meant to use fopf rather than fop - but if so, that's still
problematic. Your program should not have closed fopf until after you
were finished working with it.
 
J

James Kuyper

Yes, you are right. They are part of gtk and glib. But do you really think the problem is that library related? I guess its more to do with my understanding of C.

You can confirm that it's not library related by removing those function
calls from your example code, using the C standard libraries instead.
Then, when you post your code here, we won't have to waste time worrying
about the possibility that your problem has something to do with the
other library.
 
R

Rudra Banerjee

As per your advice, I changed the code as:

FILE *fopf = fopen(filename, "a" );
if (!fopf){
filename="Untitled.bib";
fopf= fopen(filename,"a");
}
char fop[]="Hello World";
int buf_size= strlen(fop)+1;
fwrite(fop,buf_size,1,fopf);
if(!fop){
printf("failed");
}
fclose(fopf);

gtk_label_set_text(GTK_LABEL(flabel), filename);
printf( fop, "@%s{%s,\n", strcombo, strkey );
if( strlen(strAuth)!=0)
printf( fop, "\tAuthor=\"%s\",\n", strAuth);
if( strlen(strEditor)!=0)
printf( fop, "\tEditor=\"%s\",\n", strEditor);

But still its showing seg. fault as before.

James,
thanks for your elaboration.
But, I have used fprintf instead of g_fprintf, which is, by defination," An implementation of the standard fprintf() function which supports positional parameters, as specified in the Single Unix Specification."

As such, questions about g_fprintf() are best answered in a
UNIX-oriented newsgroup, such as comp.programmer.UNIX.
Also, from http://www.gnu.org/software/libc/manual/html_node/Buffering-Concepts.html, I think fprintf is "unbuffered", as it reads/writes directlyto the file.

Why would you think that? it says "Newly opened streams are normally
fully buffered, with one exception: a stream connected to an interactive
device such as a terminal is initially line buffered." A file is
unbuffered only if you explicitly call setvbuf() to make it unbuffered.
What I am trying to achieve is read the whole file in buffer and edit the buffer only! The buffer will flush to file when that is filled....something in that way(guess I am too vague here)!

The way to do that in C is to fread() into a buffer, edit the buffer,
and then fwrite() it.

The buffer you're editing will be different from the buffer associated
with the file, but copying between those buffers is not going to cost
you much time by comparison with the file I/O. You could avoid those
copies by making both the files unbuffered, but I would recommend that
approach only if you're going to have but a single fread() and a single
fwrite(). If there are multiple reads and writes you're better letting
the C standard library handle the I/O buffer, while you concentrate on
your internal data buffer.
I was trying something like:
FILE *fopf = fopen(filename, "a" );
if (!fopf){
filename="Untitled.bib";
fopf= fopen(filename,"a");

Note: you make no attempt to check whether the second fopen() failed.
It's quite possible for it to fail, and the behavior of your program is
undefined if it does.
}
char fop[]="Hello World";
int buf_size= strlen(fop)+1;
fwrite(fop,buf_size,1,fopf);
fclose(fopf);

You also failed to check whether fwrite() or fclose() failed. Because
fopf IS buffered, a failed fclose() implies that there might still be
data in the buffer which has not yet been written to the file.
if( strlen(strAuth)!=0)
g_fprintf( fop, "\tAuthor=\"%s\",\n", strAuth);

but that caused the app to crash, with Segmentation fault (core dumped)while writing to it.

I don't have documentation for g_fprintf(), but in your first message,
you passed it a FILE* as the first argument, and in this message, you're
passing a char*. One of the two is probably incorrect. Since this is the
one that failed, it's probably the incorrect one.
I think you meant to use fopf rather than fop - but if so, that's still
problematic. Your program should not have closed fopf until after you
were finished working with it.
 
R

Rudra Banerjee

oh...sorry! the error was caused by one of the unused fprintf! So, its not crashing anymore.
But it will be of huge help for me if someone comment on if this is the right (and good)way.
 
B

Ben Bacarisse

Rudra Banerjee said:
As per your advice, I changed the code as:

FILE *fopf = fopen(filename, "a" );
if (!fopf){
filename="Untitled.bib";
fopf= fopen(filename,"a");
}

fopf may still be == NULL here. You should still test it even after
trying to open the "default" file.
char fop[]="Hello World";
int buf_size= strlen(fop)+1;

C has a way to write the directly:

int buf_size = sizeof fop;
fwrite(fop,buf_size,1,fopf);

This writes too much. You probably don't want to write 12 bytes because
that includes the null character that terminates the string.
if(!fop){
printf("failed");
}

This text can never succeed. fop is a declared array and as such the
value of fop is guaranteed never to be == 0.
fclose(fopf);

gtk_label_set_text(GTK_LABEL(flabel), filename);
printf( fop, "@%s{%s,\n", strcombo, strkey );
if( strlen(strAuth)!=0)
printf( fop, "\tAuthor=\"%s\",\n", strAuth);
if( strlen(strEditor)!=0)
printf( fop, "\tEditor=\"%s\",\n", strEditor);

But still its showing seg. fault as before.

You need to ask the compiler for more warnings. It can tell you that
fop has the wrong type for the first argument to printf so you are
either ignoring important messages or you need to ask for more of them1

<snip>

BTW, top-posting is not consider the best style here. Interleave your
comments with the message you are replying to, snipping those parts that
are not relevant to what you want to say.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,982
Messages
2,570,186
Members
46,740
Latest member
JudsonFrie

Latest Threads

Top