Hi
I'm a beginner and was wondering how to copy data from one file (have to open that file first on " ?" mode, and then modifying that data when copying it to another file) using C
thanks,
Printable View
Hi
I'm a beginner and was wondering how to copy data from one file (have to open that file first on " ?" mode, and then modifying that data when copying it to another file) using C
thanks,
See this FAQ: http://faq.cprogramming.com/cgi-bin/...&id=1043284392
To learn C, you need a book, or to work through some of the many on-line tutorials (Google has 'em!), or both.
There is so much more to C to be learned. Come on back when you have a specific problem with some exercise, or assignment. What you want to modify and how you want to modify it, are all important considerations to be sorted out.
How to copy data from an existent file to a new file inserting a line numbers at the begining of each line?
The original file are paragraphs and I have to copy the paragraphs into another file inserting a line of numbers on each line.
Example:
original file
ibvevbelfvbeflvhbefvbh
uedvheunv
undojvndfojvndfjvndfjvndfj vdfjnvdjfvn dfvjndfv dfvlndfvjdfvn
dfvjefvnef
efgioergerngenfg
copy of the file into the new one
1. ibvevbelfvbeflvhbefvbh
2. uedvheunv
3. undojvndfojvndfjvndfjvndfj vdfjnvdjfvn dfvjndfv dfvlndfvjdfvn
4.
5. dfvjefvnef
6. efgioergerngenfg
and so forth
thanks,
thanks ,,
HI
Can you review the question again and let me know if you can help ?
thanks,
Sometimes you get what you asked for:
Compile as "filecopy" and use:Code:#include <stdio.h> // for "fprintf" and "fgetc"
#include <stdlib.h> // for "exit"
// function prototypes
void fatal (int retv, char *message);
int streamline (FILE *IN);
char *buffer; // global buffer
int main (int argc, char *argv[]) { // argv[1] will be the filename to read
FILE *fstRO, *fstOUT; // argv[2] will be the filename to write
int retv, ln=1; // ln is for line number
if (argc<2) fatal(-1,"Two filenames required."); // check for them
// open the files
if ((fstRO=fopen(argv[1],"ro"))==NULL) fatal(-2,"Can't read from file #1.");
if ((fstOUT=fopen(argv[2],"w"))==NULL) fatal(-2,"Can't write out to file #2.");
while ((retv=streamline(fstRO))>0) { // read from file
fprintf(fstOUT, "%d. %s\n",ln,buffer); // write to file
ln++; // increment
free(buffer); // very important since buffer had memory allocated in streamline()
}
switch (retv) { // finished reading file
case -2: fatal(-3,"Memory allocation failure!"); // in case streamline() fails
case -1: fprintf(fstOUT, "%d. %s\n",ln,buffer); // the "special case"
break;
case 0: break;
default: break;
}
free(buffer); // less important since the program is now over
// close the files
fclose(fstRO);
fclose(fstOUT);
return 0; // THE END
}
void fatal (int retv, char *message) {
puts(message);
exit (retv);
}
int streamline (FILE *IN) { // returns a string length that INCLUDES the line terminator or 0 for last line
int chr, i=0; // i is for iteration counter
buffer=malloc(1); // begin allocating memory for the line buffer
while ((chr=fgetc(IN))!=EOF) {
if (buffer==NULL) return -2; // in case memory allocation fails
if (chr=='\n') { // reached end of line
buffer[i]='\0'; // so terminate it
return i+1;
}
buffer[i]=chr; // copy character into buffer
buffer=realloc(buffer,++i+1); // more memory for next iteration
} // End-Of-File reached
if (buffer==NULL) return -1; // last check
if (i>1) {
buffer[i]='\0'; // terminate last line if it exists with no newline
return -1; // (a normative "special case")
}
return 0; // and return 0 to indicate we're finished
}
filecopy filetocopy.txt filetocreat.txt
edit: there's actually three very minor bugs in this, and Salem found them all (see subsequent posts).
MK27's program is present.
Dallo07 has not written a single line of code.
MK27, do you see something wrong here?
Probably a good idea not to mention the bugs then...
Well obviously, because you can't find them!
Is your basis of "bug free" down to "it's produced the correct answer with a few tests, and it hasn't crashed"?
And another attack at MK27, this time Salem, lol
I would hardly call it an attack on anything but MK27's code, but in any case, if you dare to call your code bug free, then it better be bug free.Quote:
Originally Posted by Matus
Well MK27 you will be spoon feeding for a very long time then.
"Give a man a fish he is fed for a day, teach a man to fish he is fed for life"
use splint
That word is in Spanish, apparently, and means "rattler", according to the online source I checked. You probably mean charlatan, though the connection in both cases seems rather tenous.Quote:
Originally Posted by MK27
The point of both Adak and slingerland3g is that we should avoid giving a complete answer to a homework problem until it has been shown that a genuine attempt has been made for a complete solution.
> if (argc<2) fatal(-1,"Two filenames required.");
If argc is 2, what is the value of argv[2] here?
> if ((fstOUT=fopen(argv[2],"w"))==NULL)
> if ((fstRO=fopen(argv[1],"ro"))==NULL)
Which non-standard compiler extension requires "o" in the mode?
> case -1: fprintf(fstOUT, "%d. %s\n",ln,buffer); // the "special case"
Yes, very special when you have this line in the called function.
> if (buffer==NULL) return -1; // last check
> buffer=realloc(buffer,++i+1); // more memory for next iteration
And if realloc fails, what happened to the memory you used to have?
Whilst it doesn't appear to be a problem in this instance, the fact that i starts at 0 and the amount of memory starts at 1 is a recipe for off-by-one errors at some point.
Yes, I checked the spelling on line and accidently used the spanish one. The meaning is similiar, altho in english it would be more akin to someone that chatters/rattles on about things which s/he may not actually know. However, it's not prejudicial (I'm not a mean, angry person) but rather implies one is pretending or acting that way on purpose. It might even be considered a skill.
Well, I know the policy of the cboard moderators is not to do people's homework. If you want to make it a rule that nobody should and that you will remove posts that do, then go ahead. Philosophically, I don't think it will make the forum better for anyone, tho. To be honest, if someone wants to copy something they don't understand and hand it in somewhere, then I hope they aren't paying to much for their own non-education (I'm not trying to help people "cheat").
Anyway, the OP does not claim to be a student with homework, which means s/he may not have the benefit of a class of peers and all the examples and advice one can find at an institution of higher learning, so thought I was being helpful, and, in fact, inviting questions with my unorthodox programming style ;)
Which I am beginning to believe is pretty much "bug free" for sure now. ;)
Not to ruin a perfectly good round of public humiliation on another member, but I should point out I posted code yesterday that does basically exactly this task. Though mine works a little differently than MK27's since it is designed to remove or find and replace something from a different file.
Why was this reopened for discussion.
>> Which I am beginning to believe is pretty much "bug free" for sure now.
buffer=realloc(buffer, ++i+1);
The value of i is undefined. An expression must not reference a stored value more than once, in order to be defined. But that may not be the exact wording... it's in the Statements section of the Standard. Anyway, aside from what Salem pointed out earlier about the realloc statement. He's right about that - if realloc fails, you leak your own memory.
Lengthening the buffer one character at a time seems rather braindead. You might as well read character by character.
Not to mention that your streamline function will return leaving the string without a terminating zero, sometimes. And also, if streamline returns zero (which should happen if the line does not end in a newline) then you only succeed partially. Consider the last line in a file for example, which may not be followed with a newline and not copied by the program.
Lol, Hey I'm "Fluent" in spanish agreed with MK27 :), enjoy guys, heading to class atm
++i + 1 does not produce an undefined value for i. If he put ++i += i + 1, that would be a problem.
Yep, there's a bug. It should be <3.
Hmm...right again. Should just be "r"Quote:
> if ((fstRO=fopen(argv[1],"ro"))==NULL)
Which non-standard compiler extension requires "o" in the mode?
Wow, three in a row! I'm out. This should be return -2 of course.Quote:
> case -1: fprintf(fstOUT, "%d. %s\n",ln,buffer); // the "special case"
Yes, very special when you have this line in the called function.
> if (buffer==NULL) return -1; // last check
If realloc fails, the program is over because the function returns -2. All the allocation is checked. If the program is over, it doesn't matter what happened to what used to be.Quote:
> buffer=realloc(buffer,++i+1); // more memory for next iteration
And if realloc fails, what happened to the memory you used to have?
You have it backwards (the first character is 0, but that still requires 1 byte). Also, this ensures that we won't get a double free if the EOF is after a \n, since nothing is written into the (one byte) buffer.Quote:
Whilst it doesn't appear to be a problem in this instance, the fact that i starts at 0 and the amount of memory starts at 1 is a recipe for off-by-one errors at some point.
i is defined, and only referenced once here.
Definitely incorrect, which is why I like words like charlatan. If it did that (at EOF after \n), then it did nothing to the string, which means the string still has a terminator from before.Quote:
Not to mention that your streamline function will return leaving the string without a terminating zero, sometimes.
This is very very clearly addressed in the code and notes. If streamline reaches EOF after writing to buffer,Quote:
And also, if streamline returns zero (which should happen if the line does not end in a newline) then you only succeed partially. Consider the last line in a file for example, which may not be followed with a newline and not copied by the program.
buffer[i]='\0';
I am reading character by character.Quote:
Lengthening the buffer one character at a time seems rather braindead. You might as well read character by character.
> If realloc fails, the program is over because the function returns -2. All the allocation is checked. If the program is over
Yeah today maybe.
But sooner or later, you'll use realloc in the same way and you won't be exiting the program.
THEN you'll have a problem.
> You have it backwards (the first character is 0, but that still requires 1 byte).
Like I said, I didn't think there was a problem, just that the code was messy and error prone.
Example:
But that is just my two cents.Code:#include <stdlib.h>
#include <stdio.h>
int main(int argc, char **argv)
{
if(argc != 3)
puts("Usage: copyfile [from] [to]");
else
{
FILE *ifile, *ofile;
char *buffer;
size_t size, total;
ifile = fopen(argv[1], "rb");
ofile = fopen(argv[2], "wb");
if(!ifile || !ofile)
{
perror("Could not complete this operation.");
if(ifile)
fclose(ifile);
if(ofile)
fclose(ofile);
return EXIT_FAILURE;
}
if(!(buffer = malloc(0x1000))) /* 4k is sufficient */
{
fputs("Out of memory!\n", stderr);
fclose(ifile);
fclose(ofile);
return EXIT_FAILURE;
}
total = 0;
while((size = fread(in, 1, 0x1000, ifile)))
{
fwrite(out, 1, size, ofile);
total += size;
printf("\r%d bytes copied", total);
}
free(buffer);
fclose(ifile);
fclose(ofile);
}
return EXIT_SUCCESS;
}
What if I promise not to?
Messy! Is not!Quote:
> You have it backwards (the first character is 0, but that still requires 1 byte).
Like I said, I didn't think there was a problem, just that the code was messy and error prone.
Anyway, if by error prone you mean "there's some mistakes you could have made by doing it this way, but didn't" then I will take that as a compliment, Salem.
@MK27 - well, oops.
I was pretty sure I was wrong when I hit send, but it always happens that way doesn't it? I can find some creative words to describe you too, by the way. I suggest you not dish out unwarranted insults.
Oh! And who could forget this little gem.
Example:
Code:#include <stdlib.h>
#include <stdio.h>
#define IS_LESS_THAN <
int main(int the_number_of_command_line_arguments, char **the_command_line_parameter)
{
char buffer[4096];
if(the_number_of_command_line_arguments IS_LESS_THAN 3)
return EXIT_FAILURE;
snprintf(buffer, sizeof(buffer)-1, "copy %s %s",
the_command_line_parameter[1],
the_command_line_parameter[2]);
system(buffer);
return EXIT_FAILURE;
}
Oooops, I didn't notice the line number mumbo jumbo. MK27's code hardly seems brilliant. I mean come on now dude...
Code:#include <stdlib.h>
#include <stdio.h>
int main(int argc, char **argv)
{
if(argc != 3)
puts("Usage: copyfile [from] [to]");
else
{
FILE *ifile, *ofile;
char *buffer;
size_t line;
ifile = fopen(argv[1], "r");
ofile = fopen(argv[2], "w");
if(!ifile || !ofile)
{
perror("Could not complete this operation.");
if(ifile)
fclose(ifile);
if(ofile)
fclose(ofile);
return EXIT_FAILURE;
}
if(!(buffer = malloc(0x80000))) /* .5MB is sufficient */
{
fputs("Out of memory!\n", stderr);
fclose(ifile);
fclose(ofile);
return EXIT_FAILURE;
}
line = 0;
while(fgets(buffer, 0x80000, ifile))
{
fprintf(ofile, "%3d. %s", ++line, buffer);
}
free(buffer);
fclose(ifile);
fclose(ofile);
}
return EXIT_SUCCESS;
}
Well, it's not freed by you. The person using streamline will have to free it.
You can say (I guess you are saying) that it's an undocumented (as of yet) feature that your function will leave buffer in an invalid state when \n is immediately followed by EOF, and I would agree with you that one fix is to then document that when your function returns 0, buffer is invalid and should not be accessed. I will leave it to you to determine whether that's a bug in the code or a bug in the comments (since your comment about what return 0 means at the bottom is incorrect).
I'm going to claim that it's actually me and I did do it. Honest.
But, don't you think it would be going too far, after having actually written some half-brilliant code which I should never have done because it might get used in someone's homework, to then provide our negligent student with some kind of API documentation to complete the charade?
I notice Master5001 managed to streamline things a bit while sacrificing security. b/t/w, why does
equal .5mb?Code:malloc(0x80000)
I hate to be the psyche student on you but your code is neither brilliant nor worth using for homework purposes. I was going to simply correct your code but the entire way it works was too flawed to even fix it. You do realize that allocation is one of the most expensive operations you can do, right?
Since the whole exercise was already going too far, that's irrelevant.
I realize you were happy to have a solution that (seemed to) work, and you wanted to share; and if you had just done so, you probably would still have had a couple people make noises about doing people's homework, but that's mostly small potatoes (everybody has a line, but in different places), and using code as a "teachable moment" can be useful.
The flip side is that you have become a regular here -- you've started 25 threads in the last two months, after all -- and a known quantity. And posting the code that you did, calling it "brilliant" and "bug-free"; well, that's a teachable moment, too. Not just that pride goeth before a fall, but maybe to see what bug-free code actually is.
I'm getting way too philosophical for a Friday, so I'll stop.
Haha you made me laugh :-) In all seriousness, your code isn't "not-brilliant" because of how you did it. It is problematic because of the fact that global buffers are just plain messy. Simply put your code is quite excellent except that it requires the caller to do stuff to clean up after each and every call to the function. And the function is slower because of the fact that it must allocate buffers each and every call (well, probably not, malloc may be over-allocating).
Its better to do malloc(1000) than malloc(1) and incrementally increase the buffer size. What you can do is have a factor to increase your malloc by and just allocate chunks at a time.
He is right to touch on the fact that you are not considered a troll and are a regular member. Thus some of us still hold respect for you and you wouldn't wish to go around and make people feel forced into calling you a pedantic fruit-loop. Or worse yet, an idiot. Which I do not believe you to be either.
Hehe, Matt the phsyc student :), i thnk thats the correct spelling, i enjoy reading here
I'm much better at perl.
I like perl :) New York City!? (I doubt most of the people here remember those commercials to get the reference--and so you don't think I am being a random nut, I noticed MK27 is from NYC). And the h goes at the end, Matus. I dunno why, but I always want to spell it that way too.