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