Вам нужен часовой маркер в вашем списке:
puts(copycat("herp", "derp", "hurr", "durr", NULL));
В противном случае va_arg
на самом деле не знает, когда остановиться. Тот факт, что вы получаете мусор, является чистой случайностью, так как вы вызываете неопределенное поведение. Например, когда я запустил ваш код как есть, у меня возникла ошибка сегментации.
Функции переменных аргументов, такие как printf
, нуждаются в некотором указании относительно того, сколько элементов передано: printf
сам использует строку формата заранее, чтобы выяснить это.
Два основных метода - это число (или строка формата), которое полезно, когда вы не можете использовать одно из возможных значений в качестве часового (маркер в конце).
Если вы можете использовать часовой (например, NULL в случае указателей или -1 в случае неотрицательных целых чисел со знаком, это обычно лучше, поэтому вам не нужно считать элементы) (и возможно вывести количество элементов и список элементов из шага).
Имейте в виду, что puts(copycat("herp", "derp", "hurr", "durr"));
- это утечка памяти, поскольку вы выделяете память, а затем теряете указатель на нее. Использование:
char *s = copycat("herp", "derp", "hurr", "durr");
puts(s);
free (s);
- это один из способов исправить это, и вы можете добавить код проверки ошибок в случае неудачного распределения.