There are several issues and areas for improvement here.
First, there's this:
FILE *f = fopen("argv", "r");
argv in quotes, you're saying to treat whatever is in quotes as a literal string. In other words, open a file named "argv". Remove the quotes to use the string/filename contained inside argv. That should clean up this seg fault (but exposes another one later.)
Next, some programming tips. An if statement does not require an else clause. In fact, an else clause should NOT be used unless absolutely necessary. It just adds to code, decreases runtime efficiency and introduces the possibility of adding code bugs if the code is later modified. Often, this means that the bulk of the program that follows is encapsulated in this else clause - this is a bad programming practice and should be a red flag. It's an invitation for introducing a bug.
In deciding whether to use an else clause, ask this: Does the code need to do EITHER A or B at runtime? If it does, use an else clause. If the situation is just "If TRUE, do something (including terminate), and then continue", then the else is not needed and should not be used.
In this case, look at this code:
Think about what happens if buffer is NULL and if it isn't. If buffer is null, the program will terminate, end of story. If it isn't null, then the code must continue to execute. It's not a "do code block A or do code block B, based on the test". It's a case of "IF true, then termiate the program. Otherwise continue."
Now, let's talk about the file pointers. This code opens the same output files multiple times and yet never closes them. It also starts by opening the output file for write, and then for append. Like your comment said,
//if the file is already open, it really is already open. It doesn't need to be reopened.
When a file is opened in a program, it remains open until explicitly closed with an fclose() call. Opening a file multiple times is also dangerous because of the interactions that can occur when two pointers are being used to alter the file content.
Looking at the big picture, the concept is simple. When necessary, open an output file for write. Write as needed to the output file. When done, close the file. That pointer can now be used to open another file with a different name. There's also no need for preserving multiple output file names. You should only be working with one at a time.
About reading from the input file: The code is using both fgetc() and fread() calls to read data. The fgetc call is going to move the pointer one char in the file, corrupting positioning for fread. I suggest you think about how to incorporate the fread into the while statement. Read the man page for fread, particularly the return values and the input parameters.
Speaking of fread, the statement
fread (buffer, 512, 512*50, f); will read 512 * 512 * 50 = 13107200 bytes! That's 13 MB, a bit more than 512 bytes.
And of course, never use single letter variable names, except for standard usage as for loop counters. Anything that has any significance, like the pointer for the input file, deserves a descriptive name, like
infile. If you've ever tried to debug a program with widespread use of single letter vars, you'd understand. Try finding every variable named "f".
Did I mention that there's not a single call to fclose()?
If this answers your question, please click on the check mark to accept. Let's keep up on forum maintenance. ;-)