First of all, let me say that if you're new to programming you've done a great job with 'neatness' of code. It's so nice to see code with comments. :).
Anyway..
A few questions I have before I can answer..
1. Is it mandatory for u to use C? Can't u use C++? It would a LOT easier with C++ STL n all..
2. Is you file an ascii file or a binary/data file? May not be related to your problem but see http://bama.ua.edu/cgi-bin/man-cgi?fopen+3C . Ideally you should opne with "rb" as the mode. (could run into to unwanted problem otherwise depending on environment, i.e. unix/windows..)
Now to the code, a few things I think you can correct.
Line 7:
char ch, *filename (char *buf, size_t length, FILE *f);
It seems to me like compiler is not cribbing at line 7 itself (although it should), only because it thinks that you have correctly declared
1. char ch; = ch as a character
2. char *filename (char *buf, size_t length, FILE *f); =prototype/declaration for a function named "filename" (which is defined on line 55).
Function names are nothing but variables of type "function pointers". So when you use this function as an argument to gets() on line #19 compiler tries to match the expected type (char*) and supplied type (char*(*)(char*, size_t, FILE*)). As they don't match compiler tries to convert supplied type to the expected type using built-in (and user-defined, viz not applicable in your case) conversion operators/rules. In this case a pointer to function pointer can't be converted to char* so compiler gives an error.
When you change filename's declaration to filename[40]. Compiler sees "filename" as a "char*" which is exactly what is required by gets().
So first thing you can correct is: declare filename as char filename[40] .Second problem with the code is that you have opened the file in text /ascii mode and you are allocating teh buffer (into which you plan to read the data) as if the file is a binary/data file. The way data is stored in binary/data file is different than an ascii file (See http://www.learn-programming.za.net/programming_c_learn10.html )
. In simple words if your file is a binary/data file then sizeof buffer to be allocated would be same as size of file (or number of bytes ni file). But if file is an ascii file that is not true. (if a single number say 1000 is stored in an ascii file file size would be 4 bytes, if it's stored in a binary file it'll be sizeof(int) ).Third and biggest problem is you have a function AND a variable with same name (after you make the suggested correction) ! This is NEVER a good idea. Remember the rule of thumb "Never use/introduce/declare same name twice in same scope." Name here refers to a variable/function/struct-type...
So pick any one naming notation/convention of you choice and follow it. E.g. hungarian is a famous one. If you are not comfortable with that at least think of a story like name for your variables for they dn't clash. E.g. change char filename[40] to char input_filename[40] .
The other error "57: error: declaration of 'char buf[40]' shadows a parameter" is that char buf[40] declared on line 57 hides the other variable in same scope which is teh function argument char *filename ( char *buf , size_t length, FILE *f) . May be you can change line 57 to char* tmp_buf