Intercalar duas strings em C

Tenho a dúvida de fazer intercalar com duas strings de tamanhos diferentes. Tenho esse código:

char p1[100], p2[100],p3[100];
	int i, k;
	gets(p1);
	gets(p2);
	if(strlen(p1)==strlen(p2)){
		k=0;
		for(i=0; i<strlen(p1); i=i+1){
			p3[k] = p1[i];
			p3[k+1] =p2[i];
			k=k+2;
		}
		
		p3[k]='\0';
		printf("%s", p3);
	}

Sendo de tamanho iguais ele faz, mas quero o caso de teste de digitar ‘Quarta’ e ‘Segunda’ ele me retorne ‘QSueagrutnada’, quando tentei fazer usando o mesmo código acima ele me retorna isso ‘QSueagrutnad’ faltando o ‘a’ no final. Não sei como tratar isso.

Tem certeza que foi esse código que você usou mesmo? Porque ele tem if(strlen(p1)==strlen(p2)), ou seja, só vai fazer tudo que tem ali dentro se as strings tiverem o mesmo tamanho (o que claramente no seu exemplo não tem).

Mas enfim, existe um problema de ficar chamando strlen toda hora (explicado em detalhes aqui). Basicamente, toda vez que você chama strlen, ele precisa percorrer toda a string para saber o tamanho, então você só deveria chamá-la quando realmente necessário. Em um loop. por exemplo, não é uma boa porque para cada iteração você terá que percorrer novamente a string para ver o tamanho (isso acontece porque strings em C são mutáveis e o tamanho pode ter mudado durante o loop, por isso ele acaba tendo que verificar novamente toda hora).

Enfim, eu usaria strlen apenas uma vez para cada string, para saber o tamanho total a ser alocado para a string final. Depois, você itera pelas strings verificando se o caractere não é o \0 (o null terminator, o “caractere nulo” usado como terminador de strings). Algo assim:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void juntar(const char *s1, const char *s2, char *output) {
    // enquanto nenhuma delas terminar
    while (*s1 != '\0' && *s2 != '\0') {
        *output++ = *s1++;
        *output++ = *s2++;
    }
    // se saiu do while é porque uma delas terminou, então tenta adicionar o que falta nelas
    while (*s1 != '\0') // se foi a primeira que não terminou
        *output++ = *s1++;
    while (*s2 != '\0') // se foi a segunda que não terminou
        *output++ = *s2++;
    *output = '\0'; // coloca o terminador de string
}

int main() {
    char *str1 = "Quarta";
    char *str2 = "Segunda";
    // aloca espaço para a string final, será a soma do tamanho das 2 strings
    // lembrando de alocar 1 byte a mais, para o terminador de strings
    char *output = malloc(strlen(str1) + strlen(str2) + 1);
    juntar(str1, str2, output);
    printf("%s", output); // QSueagrutnada
    return 0;
}

Ou seja, primeiro eu avanço em ambas as strings, colocando um caractere de cada uma delas na string final. Quando uma delas terminar, eu vejo qual que ainda não terminou e coloco os caracteres restantes.

Talvez você não esteja familiarizado com aritmética de ponteiros, mas esse é um código bem idiomático em C. Se achou complicado, uma outra opção é usar o loop tradicional mesmo:

void juntar(const char *s1, const char *s2, char *output) {
    // enquanto nenhuma delas terminar
    int i1 = 0, i2 = 0, j = 0;
    while(s1[i1] != '\0' && s2[i2] != '\0') {
        output[j] = s1[i1];
        output[j + 1] = s2[i2];
        j += 2;
        i1++;
        i2++;
    }
    // se saiu do for acima é porque uma delas terminou, então tenta adicionar o que falta nelas
    while(s1[i1] != '\0') { // se foi a primeira que não terminou
        output[j] = s1[i1];
        j++;
        i1++;
    }
    while(s2[i2] != '\0') { // se foi a segunda que não terminou
        output[j] = s2[i2];
        j++;
        i2++;
    }
    output[j] = '\0'; // coloca o terminador de string
}

Outro detalhe (não diretamente relacionado ao problema, mas aproveitando o tópico) é que gets não é uma função muito segura para ler dados do stdin (veja aqui os detalhes), e uma alternativa melhor é usar fgets - mas o preço para ter mais “segurança” é ter um pouco mais de trabalho:

char str1[100], str2[100];
if (fgets(str1, 100, stdin) != 0) {
    // fgets retorna a quebra de linha, então devemos removê-la
    str1[strcspn(str1, "\n")] = '\0';
} else {
    printf("Erro ao ler\n");
    exit(1);
}
if (fgets(str2, 100, stdin) != 0) {
    // fgets retorna a quebra de linha, então devemos removê-la
    str2[strcspn(str2, "\n")] = '\0';
} else {
    printf("Erro ao ler\n");
    exit(1);
}

// ... resto do código igual