Funções de String
Funções de string são como chaves e chaves de fenda em uma caixa de ferramentas — cada ferramenta resolve um problema específico: copiar, concatenar, comparar, buscar. Domine-as, e você lidará com texto com confiança.
Visão geral do string.h
<string.h> é o arquivo de cabeçalho principal para operações de string na biblioteca padrão C, fornecendo funções para copiar, concatenar, comparar e buscar. Você deve incluí-lo antes de usar:
c #include <string.h>
strcpy e strncpy
strcpy
strcpy copia a string de origem para o vetor de destino, incluindo \0:
c char dest[20]; strcpy(dest, "Hello World"); printf("%s\n", dest);
Protótipo: char *strcpy(char *dest, const char *src);
strcpy não verifica o tamanho do buffer de destino. Se a string de origem for maior que o vetor de destino, ela escreve fora dos limites. Garanta que o vetor de destino seja grande o suficiente antes de usá-la.
strncpy
strncpy limita o número máximo de bytes a copiar, tornando-a mais segura:
c char dest[6]; strncpy(dest, "Hello World", sizeof(dest) - 1); dest[sizeof(dest) - 1] = '\0'; printf("%s\n", dest);
Protótipo: char *strncpy(char *dest, const char *src, size_t n);
strncpy copia no máximo n bytes. Se a string de origem for menor que n, as posições restantes são preenchidas com \0; se a string de origem tiver n bytes ou mais, ela não adiciona \0 automaticamente. Portanto, você deve adicioná-lo manualmente.
\0 ao usar strncpy e adicione \0 manualmente após a cópia.
strcat e strncat
strcat
strcat anexa a string de origem ao final da string de destino:
c char buf[50] = "Hello"; strcat(buf, " World"); printf("%s\n", buf);
Protótipo: char *strcat(char *dest, const char *src);
O \0 existente no final da string de destino é sobrescrito, e um novo \0 é colocado após o resultado concatenado.
strcat não verifica o tamanho do buffer.
strncat
strncat limita o número máximo de caracteres a anexar e adiciona \0 automaticamente:
c char buf[10] = "Hi"; strncat(buf, " World!", sizeof(buf) - strlen(buf) - 1); printf("%s\n", buf);
Protótipo: char *strncat(char *dest, const char *src, size_t n);
Ela anexa no máximo n caracteres, depois adiciona \0 automaticamente. É mais segura que strncpy porque garante terminação nula.
strcmp e strncmp
strcmp
strcmp compara duas strings lexicograficamente, caractere por caractere:
c int result = strcmp("abc", "abd");
Significado dos valores de retorno:
< 0: s1 é menor que s2= 0: s1 é igual a s2> 0: s1 é maior que s2
c if (strcmp(s1, s2) == 0) { printf("Equal\n"); }
strcmp para comparar strings, nunca ==. == compara endereços de ponteiros, não conteúdos de strings.
strncmp
strncmp compara apenas os primeiros n caracteres:
c if (strncmp(str, "GET ", 4) == 0) { printf("GET request\n"); }
Útil para comparar prefixos ou limitar o escopo da comparação.
Exemplo
Ordene um vetor de strings em ordem lexicográfica:
`c #include <stdio.h> #include <string.h>
void sort_strings(char arr[][32], int n) { int i, j; char temp[32];
for (i = 0; i < n - 1; i++) {
for (j = 0; j < n - 1 - i; j++) {
if (strcmp(arr[j], arr[j + 1]) > 0) {
strcpy(temp, arr[j]);
strcpy(arr[j], arr[j + 1]);
strcpy(arr[j + 1], temp);
}
}
}
}
int main(void) { char names[5][32] = { "david", "alice", "charlie", "bob", "eve" }; int i;
sort_strings(names, 5);
for (i = 0; i < 5; i++) {
printf("%s\n", names[i]);
}
return 0;
} `
ext alice bob charlie david eve
strlen
strlen retorna o comprimento efetivo de uma string (não incluindo \0):
c char s[] = "Hello"; printf("%zu\n", strlen(s)); printf("%zu\n", sizeof(s));
Saída: 5 e 6. strlen conta até \0; sizeof inclui \0.
strlen percorre a string para encontrar \0, com complexidade de tempo O(n). Se você usa o comprimento da mesma string múltiplas vezes, armazene o resultado em cache:
c size_t len = strlen(s); for (size_t i = 0; i < len; i++) { }
Em vez de chamar strlen na condição do laço a cada iteração.
strchr e strrchr
strchr encontra a primeira ocorrência de um caractere em uma string:
c const char *p = strchr("Hello World", 'o'); if (p != NULL) { printf("Found: %s\n", p); }
Saída: "o World". Retorna um ponteiro para aquele caractere, ou NULL se não encontrado.
strrchr encontra a última ocorrência de um caractere:
c const char *p = strrchr("Hello World", 'o'); if (p != NULL) { printf("Last occurrence: %s\n", p); }
Saída: "orld".
strstr
strstr encontra a primeira ocorrência de uma substring em uma string:
c const char *p = strstr("Hello World", "World"); if (p != NULL) { printf("Substring at: %s\n", p); }
Saída: "World". Retorna NULL se não encontrado.
Encontrando todas as ocorrências:
c const char *text = "abababab"; const char *p = text; while ((p = strstr(p, "ab")) != NULL) { printf("Position %ld\n", (long)(p - text)); p++; }
Após cada busca, avance o ponteiro em uma posição e continue procurando ocorrências subsequentes.
Implementações personalizadas de funções de string
Entender como as funções padrão funcionam internamente ajuda a dominar a essência das operações de string.
strlen personalizado
c size_t my_strlen(const char *s) { size_t len = 0; while (s[len] != '\0') { len++; } return len; }
strcpy personalizado
c char *my_strcpy(char *dest, const char *src) { char *d = dest; while ((*d++ = *src++) != '\0') { } return dest; }
Esta forma compacta: *d++ = *src++ copia o caractere primeiro, depois ambos os ponteiros avançam, até que \0 seja copiado.
strcmp personalizado
c int my_strcmp(const char *s1, const char *s2) { while (*s1 == *s2) { if (*s1 == '\0') return 0; s1++; s2++; } return (unsigned char)*s1 - (unsigned char)*s2; }
Compare caractere por caractere: continue enquanto forem iguais, pare ao encontrar uma diferença ou \0. Retorne a diferença para indicar a ordem. A conversão para unsigned char garante que valores negativos de caracteres não afetem o resultado da comparação.
Exemplo
strcat personalizado e teste:
`c #include <stdio.h>
char *my_strcat(char *dest, const char *src) { char *d = dest; while (*d != '\0') { d++; } while ((*d++ = *src++) != '\0') { } return dest; }
int main(void) { char buf[50] = "Hello"; my_strcat(buf, ", "); my_strcat(buf, "World!"); printf("%s\n", buf); return 0; } `
ext Hello, World!
Primeiro encontre o \0 no final de dest, depois copie o conteúdo de src a partir daquela posição.
❓ Perguntas Frequentes
P: Por que strncpy não adiciona
\0automaticamente? R:strncpyfoi originalmente projetada para preencher buffers de comprimento fixo (como campos de nome de arquivo): preenche com\0quando menor que n, mas não adiciona\0quando atinge n bytes. Quando usada comostrcpymais segura, você deve adicionar\0manualmente.
P: O valor numérico específico retornado por
strcmpimporta? R: Você deve apenas verificar se é positivo, negativo ou zero — não dependa do valor exato. Implementações diferentes retornam diferenças diferentes; código portátil usa apenas==0,<0,>0.
P:
strcaté ineficiente para múltiplas concatenações — o que fazer? R: Cadastrcatpercorre dest do início ao fim antes de anexar, tornando a eficiência total O(n^2) para múltiplas concatenações. Você pode rastrear manualmente a posição final atual e anexar diretamente a partir dela.
P: Qual o sentido de implementar funções de string você mesmo? R: Entender princípios internos, perguntas comuns em entrevistas, e desenvolvimento embarcado onde a biblioteca padrão pode não estar disponível. No entanto, prefira funções da biblioteca padrão em projetos reais — elas são testadas e otimizadas.
📖 Resumo
strcpy/strncpycopiam strings; strncpy é mais segura mas requer terminação\0manualstrcat/strncatconcatenam strings; strncat adiciona\0automaticamentestrcmp/strncmpcomparam strings; nunca use==para comparar conteúdo de stringsstrchr/strrchrbuscam caracteres;strstrbusca substrings- Implementações personalizadas ajudam a entender princípios internos; use a biblioteca padrão em projetos reais
📝 Exercícios
- Escreva uma função
oid str_tolower(char *s)que converta todas as letras maiúsculas de uma string para minúsculas. - Escreva uma função
int str_count_char(const char *s, char ch)que conte quantas vezes o caracterechaparece na strings. - Sem usar nenhuma função de string.h, escreva
my_strstrpara implementar busca de substring.



