Should I put many functions into one file? Or, more or less, one function per file?
IMHO, you should combine items into logical groupings and create your files based on that.
When I'm writing functions, there are often a half a dozen or so that are tightly related to each other. I tend to put them together in a single header and implementation file.
When I write classes, I usually limit myself to one heavyweight class per header and implementation file. I might add in some convenience functions or tiny helper classes.
If I find that an implementation file is thousands of lines long, that's usually a sign that there's too much there and I need to break it up.
One function per file could get messy in my opinion. Imagine if POSIX and ANSI C headers were made the same way.
#include <strlen.h>
#include <strcpy.h>
#include <strncpy.h>
#include <strchr.h>
#include <strstr.h>
#include <malloc.h>
#include <calloc.h>
#include <free.h>
#include <printf.h>
#include <fprintf.h>
#include <vpritnf.h>
#include <snprintf.h>
One class per file is a good idea though.
We use the principle of one external function per file. However, within this file there may be several other "helper" functions in unnamed namespaces that are used to implement that function.
In our experience, contrary to some other comments, this has had two main benefits. The first is build times are faster as modules only need to be rebuilt when their specific APIs are modified. The second advantage is that by using a common naming scheme, it is never necessary to spend time searching for the header that contains the function you wish to call:
// getShapeColor.h
Color getShapeColor(Shape);
// getTextColor.h
Color getTextColor(Text);
I disagree that the standard library is a good example for not using one (external) function per file. Standard libraries never change and have well defined interfaces and so neither of the points above apply to them.
That being said, even in the case of the standard library there are some potential benefits in splitting out the individual functions. The first is that compilers could generate a helpful warning when unsafe versions of functions are used, e.g. strcpy vs. strncpy, in a similar way to how g++ used to warn for inclusion of <iostream.h> vs. <iostream>.
Another advantage is that I would no longer be caught out by including memory when I want to use memmove!