02.04
2021
Há alguns meses apareceu na lista cppbrasil uma dúvida, como retornar o(s) caracteres do meio de uma string. Por exemplo:
- AMARELO -> R
- VERMELHO -> ME
- AZUL -> ZU
- VERDE -> R
Na verdade houve uma discussão em torno do enunciado de fato, e o pessoal chegou a conclusão que o enunciado estava errado. Assim vamos considerar os exemplos acima:
Solução em C
#include <stdio.h>
#include <string.h>
void middle(const char *s, char *m) {
if (!s || !m)
return;
if (strlen(s) % 2 == 0) {
// even
strncpy(m, &s[strlen(s)/2] - 1, 2);
m[2] = '\x0';
} else {
strncpy(m, &s[strlen(s)/2], 1);
m[1] = '\x0';
}
}
int main() {
char s1[] = "AMARELO";
char s2[] = "VERMELHO";
char m[3] = "";
middle(s1, m);
printf("middle(%s): %s\n", s1, m);
middle(s2, m);
printf("middle(%s): %s\n", s2, m);
}
A chamada da função recebe dois parâmetros, o primeiro é a string de entrada, e o segundo é o buffer de saída, que deve ter no mínimo 3 caracteres, As melhores práticas da linguagem C indicam que os buffers devem ser alocados pela função que faz a chamada, por isso a saída é um parâmetro da função.
O código acima gera a seguinte saída:
middle(AMARELO): R
middle(VERMELHO): ME
Conforme esperado.
Solução em C++
Em C++ a solução é um pouco mais simples, pois não precisamos nos preocupar com o gerenciamento dos ponteiros. Assim:
#include <stdio.h>
#include <string.h>
d
void middle(const char *s, char *m) {
if (!s || !m)
return;
if (strlen(s) >= 0 && strlen(s) <= 2)
strcpy(m, s);
if (strlen(s) % 2 == 0) {
// even
strncpy(m, &s[strlen(s)/2] - 1, 2);
m[2] = '\x0';
} else {
strncpy(m, &s[strlen(s)/2], 1);
m[1] = '\x0';
}
}
int main() {
char s1[] = "AMARELO";
char s2[] = "VERMELHO";
char m[3] = "";
middle(s1, m);
printf("middle(%s): %s\n", s1, m);
middle(s2, m);
printf("middle(%s): %s\n", s2, m);
}
E a saída idêntica ao exemplo em C:
middle(AMARELO): R
middle(VERMELHO): ME
Desafio
Para dificultar que tal dividir a string em três partes? A parte do meio, a da esquerda e da direita. E pra deixar ainda mais difícil a versão C++ tem que retornar três strings de uma vez e utilizar um único argumento.
Comentários
#include
#include
// SEM O IF!!!!
void middle(const char *s, char *m) {
int len;
if (!s || !m) return;
len = strlen(s);
strncpy(m, &s[len/2] – 1 + (len%2), 2-(len%2));
m[2-(len%2)] = ‘\x0’;
}
int main() {
char s1[] = “AMARELO”;
char s2[] = “VERMELHO”;
char m[3] = “”;
middle(s1, m);
printf(“middle(%s): %s\n”, s1, m);
middle(s2, m);
printf(“middle(%s): %s\n”, s2, m);
}
Boa Davisão. Mandou bem!