Strings — Básico
Uma string em C é como um colar terminado com uma conta transparente — cada conta é um caractere, e a última é o terminador invisível
\0que sinaliza "o colar termina aqui".
Vetores de caracteres e strings
C não tem um tipo string dedicado. Uma string é essencialmente um vetor de caracteres terminado por \0 (o caractere nulo). O valor ASCII de \0 é 0, e ele marca o fim da string.
c char str[6] = {'H', 'e', 'l', 'l', 'o', '\0'};
Este vetor tem 6 elementos: 5 caracteres visíveis mais 1 \0. Sem \0, é apenas um vetor de caracteres comum e não pode ser usado como string.
Literais de string (aspas duplas) adicionam \0 automaticamente no final:
c char str[] = "Hello";
O comprimento do vetor é 6 (5 caracteres + 1 \0); o compilador calcula automaticamente. Você também pode especificar um comprimento maior; as posições extras são preenchidas com \0:
c char str[10] = "Hello";
str[5] até str[9] são todos \0.
'H' denotam um caractere (1 byte); aspas duplas "Hello" denotam uma string (com um \0 implícito). Eles não são a mesma coisa.
Declaração e inicialização de strings
Estilo de vetor de caracteres
c char s1[] = "abc"; char s2[10] = "abc"; char s3[] = {'a', 'b', 'c', '\0'};
Todos os três são equivalentes à string "abc". Note que s3 requer um \0 adicionado manualmente.
Estilo de ponteiro de caractere
c const char *s4 = "abc";
s4 aponta para o primeiro caractere de um literal de string. Literais de string são armazenados em uma região somente leitura; tentar modificá-los é comportamento indefinido:
c s4[0] = 'A';
Isso é errado. Vetores de caracteres, no entanto, são modificáveis:
c s1[0] = 'A';
Legal — o conteúdo de s1 torna-se "Abc".
const ao apontar um ponteiro para um literal de string; o compilador avisará se você tentar modificá-lo.
Ponteiros vs vetores
c char arr[] = "hello"; const char *ptr = "hello";
rré um vetor: memória é alocada na pilha, conteúdo pode ser modificado,sizeof(arr)é 6ptré um ponteiro: aponta para um literal de string em memória somente leitura,sizeof(ptr)é o tamanho do ponteiro (4 ou 8 bytes)
Entrada e saída de strings
printf e scanf
Use o especificador de formato %s para entrada e saída de strings:
c char name[20]; scanf("%s", name); printf("Hello, %s!\n", name);
scanf para de ler ao encontrar espaços em branco (espaço, nova linha, tabulação), então não consegue ler uma linha inteira contendo espaços.
scanf não verifica o tamanho do buffer; entrada que excede o comprimento do vetor causa estouro. Você pode limitar o comprimento de leitura:
c scanf("%19s", name);
Isso lê no máximo 19 caracteres, deixando 1 posição para \0.
puts e gets
puts imprime uma string e adiciona automaticamente uma nova linha:
c char msg[] = "Hello"; puts(msg);
Isso é equivalente a printf("%s\n", msg);.
gets lê uma linha inteira (incluindo espaços) até uma nova linha:
c char line[100]; gets(line);
fgets
gets é a substituição segura para gets:
c char line[100]; fgets(line, sizeof(line), stdin);
Os parâmetros são: o buffer de armazenamento, o número máximo de bytes a ler (incluindo \0), e o fluxo de entrada. gets retém a nova linha no final da string (se uma nova linha foi lida e ainda há espaço).
Padrão comum para remover a nova linha final:
`c #include <stdio.h> #include <string.h>
int main(void) { char line[100]; fgets(line, sizeof(line), stdin);
int len = strlen(line);
if (len > 0 && line[len - 1] == '\n') {
line[len - 1] = '\0';
}
printf("[%s]\n", line);
return 0;
} `
Exemplo
Leia o nome do usuário e uma linha de autoapresentação:
`c #include <stdio.h> #include <string.h>
void trim_newline(char *s) { int len = strlen(s); if (len > 0 && s[len - 1] == '\n') { s[len - 1] = '\0'; } }
int main(void) { char name[30]; char intro[200];
printf("Enter your name: ");
fgets(name, sizeof(name), stdin);
trim_newline(name);
printf("Introduce yourself: ");
fgets(intro, sizeof(intro), stdin);
trim_newline(intro);
printf("\n--- Personal Info ---\n");
printf("Name: %s\n", name);
printf("Intro: %s\n", intro);
return 0;
} `
` ext Enter your name: Alice Introduce yourself: I am a C beginner
--- Personal Info --- Name: Alice Intro: I am a C beginner `
A função strlen
strlen é declarada em <string.h> e retorna o comprimento da string (não incluindo \0):
`c #include <string.h>
char s[] = "Hello"; printf("%zu\n", strlen(s)); `
Saída: 5. Note que sizeof(s) é 6 (incluindo \0), enquanto strlen(s) é 5 (excluindo \0).
Como strlen funciona: conta caracteres do início até encontrar \0:
c size_t my_strlen(const char *s) { size_t len = 0; while (s[len] != '\0') { len++; } return len; }
Se um vetor de caracteres não termina com \0, strlen continuará lendo até encontrar acidentalmente um byte zero, o que é muito perigoso.
Introdução a ponteiros de caracteres
Um ponteiro de caractere pode apontar tanto para um vetor de caracteres quanto para um literal de string:
`c char arr[] = "world"; const char *ptr = "world";
ptr = arr; printf("%s\n", ptr); `
Um ponteiro pode ser reatribuído para apontar para uma string diferente, mas um nome de vetor é uma constante e não pode ser modificado:
c ptr = "another string";
Legal. Mas:
c arr = "another string";
Ilegal — um nome de vetor não pode ser atribuído.
Percorrendo uma string com ponteiro:
c const char *p = "Hello"; while (*p != '\0') { printf("%c", *p); p++; } printf("\n");
*p desreferencia para obter o caractere atual; p++ move para a próxima posição de caractere. O passo do ponteiro é determinado pelo tipo apontado; char * move 1 byte por passo.
Exemplo
Imprima uma string de trás para frente usando um ponteiro de caractere:
`c #include <stdio.h> #include <string.h>
void print_reverse(const char *s) { const char *p = s + strlen(s) - 1; while (p >= s) { putchar(*p); p--; } putchar('\n'); }
int main(void) { print_reverse("Hello"); print_reverse("ABCDEF"); return 0; } `
ext olleH FEDCBA
Primeiro, mova o ponteiro p para o último caractere da string (uma posição antes de \0), depois imprima os caracteres de trás para frente.
❓ Perguntas Frequentes
P: Qual a diferença entre
'a'e"a"? R:'a'é uma constante de caractere ocupando 1 byte;"a"é uma constante de string ocupando 2 bytes ('a' mais '\0'), e seu tipo échar[].
P: Por que
sizeofestrlendão resultados diferentes para strings? R:sizeofretorna a memória total ocupada pelo vetor (incluindo \0);strlenretorna o número de caracteres antes de \0.
P: O que acontece quando
getslê uma nova linha? R:getsarmazena a nova linha no buffer. Tipicamente você precisa verificá-la manualmente e substituí-la por\0para removê-la.
P: Posso modificar o conteúdo de um literal de string através de um ponteiro de caractere? R: Não. Literais de string são armazenados em um segmento somente leitura; modificação é comportamento indefinido. Use um vetor de caracteres se precisar modificar o conteúdo.
📖 Resumo
- Strings em C são vetores de caracteres terminados por
\0;\0é o que as funções de string usam para detectar o fim - Vetores de caracteres permitem modificação do conteúdo; ponteiros de caracteres apontando para literais não
- Use
getsem vez degetspara ler strings; sempre especifique o tamanho do buffer strlenretorna o número de caracteres efetivos;sizeofretorna o tamanho total do vetor- Ponteiros de caracteres podem percorrer uma string, movendo uma posição char por passo
📝 Exercícios
- Escreva um programa que use
getspara ler uma linha de texto e conte o número de letras, dígitos e outros caracteres. - Escreva uma função
oid str_replace_char(char *s, char old, char new_ch)que substitua todas as ocorrências deoldna stringsporew_ch. - Escreva uma função que calcule o comprimento de uma string usando ponteiros de caracteres, sem usar
strlen.



