Having a generic bland name with varying suffixes is less expressive that using names that describe the things named.  So names like name_with_backslash, name_with_slash and tent_picture would be clearer.  Alternatively, have an array with the generic bland name and iterate over it; that makes it easy to extend the test.
```
const char *invalid_names[] = { "back\\slash", "draco/harry", "back/", "\\front", "tent//\\picture" };
const char *valid_names[] = { "co:lon", "se;mi", "name@host", "horizon\tal space", "Loadsa £oot", "dollar$", "com,ma", "&, per se, &", "exclamation !", "question ?", "\ve\rtical\nspace\f" };
```
Also, note that you should check that a name with a *single* slash is rejected (both your examples have it doubled, like the backslash, which needed it in order to appear just once); and that the check catches  bad characters at diverse positions in the name, not only at the end.
The examples I've given of "valid" usernames are, incidentally, mostly suggestions for things that probably shouldn't be.
Consider using strspn(username, valid_username_characters) == strlen(username) as test.