use splint
C programming resources:
GNU C Function and Macro Index -- glibc reference manual
The C Book -- nice online learner guide
Current ISO draft standard
CCAN -- new CPAN like open source library repository
3 (different) GNU debugger tutorials: #1 -- #2 -- #3
cpwiki -- our wiki on sourceforge
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.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.
Look up a C++ Reference and learn How To Ask Questions The Smart WayOriginally Posted by Bjarne Stroustrup (2000-10-14)
> 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.
If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
If at first you don't succeed, try writing your phone number on the exam paper.
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.
C programming resources:
GNU C Function and Macro Index -- glibc reference manual
The C Book -- nice online learner guide
Current ISO draft standard
CCAN -- new CPAN like open source library repository
3 (different) GNU debugger tutorials: #1 -- #2 -- #3
cpwiki -- our wiki on sourceforge
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"> 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.> 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.> 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.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.
C programming resources:
GNU C Function and Macro Index -- glibc reference manual
The C Book -- nice online learner guide
Current ISO draft standard
CCAN -- new CPAN like open source library repository
3 (different) GNU debugger tutorials: #1 -- #2 -- #3
cpwiki -- our wiki on sourceforge
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.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,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.Lengthening the buffer one character at a time seems rather braindead. You might as well read character by character.
C programming resources:
GNU C Function and Macro Index -- glibc reference manual
The C Book -- nice online learner guide
Current ISO draft standard
CCAN -- new CPAN like open source library repository
3 (different) GNU debugger tutorials: #1 -- #2 -- #3
cpwiki -- our wiki on sourceforge
> 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.
If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
If at first you don't succeed, try writing your phone number on the exam paper.
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!> 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.
C programming resources:
GNU C Function and Macro Index -- glibc reference manual
The C Book -- nice online learner guide
Current ISO draft standard
CCAN -- new CPAN like open source library repository
3 (different) GNU debugger tutorials: #1 -- #2 -- #3
cpwiki -- our wiki on sourceforge