> lineptr = (char **) malloc(sizeof(char *) * students);
You've already included stdlib.h, so remove the cast.
If you still get a warning, then stop compiling your C program with a C++ compiler.
But that might be tricky, since you're declaring a lot of variables in the middle of the code.
Now whilst this is valid in C99, finding a C99 compiler isn't that easy. GCC is pretty close; MS Visual studio will never be C99.
Also, use the style laserlight suggested, namely
p = malloc( num * sizeof(*p) );
It is a lot easier to remember, and will keep working even if the type of the pointer changes (one less edit to maintain).
> fseek(fp, 0l, 0);
Use the SEEK_SET constant (or whatever is appropriate here).
You're passing buf to a lot of functions, but it is only acting as a local variable.
Use
char buf[SIZE];
if you're NOT using it to actually return a result.
A good example usage is get_qstnumber()
> file_name()
You still risk buffer overflow here if the buffer is full, and then you try to strcat() a string onto the end of it.
> printf(msg);
Use fputs(msg), or print("%s",msg);
NEVER pass an unknown string as the format string to printf.
Any stray % characters will spell trouble.
> initrand();
This should really be called once at the start of main.
As it is, it is called inside a loop, which will have the effect of making it a lot less random.
Other than that, it's looking pretty good.
Compared to a lot of stuff posted here, the indentation is very understandable.