It doesn't matter what type of file it is, text/binary only affects how it's opened. If you open a file in binary mode, you will read the data exactly as appears in its external representation. On the other hand, if you open a file in text mode, you will read data that has been broken up into lines by the C implementation, with each line (or at least what the implementation considers a line) terminated by the '\n' character.
You have your mode string wrong. "r+b" means ``open a binary file for reading AND writing'' and "w+b" means ``create a binary file (or truncate to zero length if it exists) for reading AND writing''. You want "rb" and "wb", which will open two streams in reading and writing mode, respectively.
Your calls to fclose are incorrect in both of these branches:
- if(fp==NULL) ...
- if(sp==NULL) ...
Since a null pointer is passed to fclose in both cases. Furthermore, you don't exit the program in any of these branches, so you'll be passing null pointers to fgetc, fputc, and fclose as well. Here's what you could do instead:
- Make the first call to fopen.
- If it returns a null pointer, emit an error (preferably on stderr), then exit (preferably with the status EXIT_FAILURE).
- Make the second call to fopen.
- If it returns a null pointer, call fclose with the value returned by the first
call to fopen, emit an error, then exit.
The type used for 'ch' may not be large enough to store the value returned by fgetc (if char is unsigned or EOF is less than CHAR_MIN). If it's signed and EOF is within the range of char, you may still have problems reading data that gets the same value as EOF, due to the type conversion. In any case, you should store it in an int when checking for EOF.
Aside from those errors, there isn't much else wrong with it. It can be helpful to check the return value of fclose, particularly on writes, and emit a message if any errors happened to occur.