Автор заметил что вывод разный, то что он сам направил вывод в файл он в курсе :)
Узнать пишем ли мы в терминал можно так:
isatty(fileno(stdout));
istty находится в io.h, а fileno в stdio.h
И ls, действительно смотрит если вывод в терминал - то в одну строку, иначе - в несколько:
https://github.com/coreutils/coreutils/blob/master...