Strings (cadeias de caracteres)
O C não tem um tipo string - só arrays de caracteres terminados em zero. Veja como trabalhar com eles com segurança.
- Explicar como o C guarda strings com um terminador nulo
- Usar
strlen,strcpy/snprintfestrcmpcorretamente - Ler uma linha de texto com segurança usando
fgets
Uma string em C é um array de char cujo último caractere é o terminador nulo '\0' - um byte com valor zero. Toda função de string depende dele: esse zero é o único jeito de saber onde a string termina.
1#include <stdio.h>
2
3int main(void) {
4 char word[] = "Hi!"; // 4 bytes: 'H' 'i' '!' '\0'
5 printf("%s has %zu bytes\n", word, sizeof word);
6 for (int i = 0; word[i] != '\0'; i++) {
7 printf("word[%d] = '%c'\n", i, word[i]);
8 }
9 return 0;
10}Hi! has 4 bytes word[0] = 'H' word[1] = 'i' word[2] = '!'
A string "Hi!" tem 3 caracteres visíveis, mas ocupa 4 bytes. Esquecer de deixar espaço para o terminador é um dos bugs mais comuns em C. Ao dimensionar um buffer, sempre pense em "tamanho + 1".
Literais de string e ponteiros para char
char name[] = "Ada"; cria o seu próprio array modificável, copiado do literal. Já const char *name = "Ada"; aponta para o próprio literal, que mora em memória somente leitura - tentar modificá-lo é comportamento indefinido. É por isso que o ponteiro é declarado const: use-o para strings que você só lê.
O kit de ferramentas de <string.h>
| Função | Faz |
|---|---|
strlen(s) | número de caracteres antes do '\0' (sem contá-lo) |
strcmp(a, b) | compara: 0 se forem iguais, negativo se a vier antes na ordem, positivo caso contrário |
strcpy(dest, src) | copia src para dest - sem verificar o tamanho |
strcat(dest, src) | acrescenta src ao fim de dest - sem verificar o tamanho |
snprintf(dest, size, fmt, ...) | printf num buffer, nunca escrevendo mais que size bytes |
1#include <stdio.h>
2#include <string.h>
3
4int main(void) {
5 const char *password = "hunter2";
6 char attempt[] = "hunter2";
7
8 if (password == attempt) {
9 printf("== says equal\n");
10 }
11 if (strcmp(password, attempt) == 0) {
12 printf("strcmp says equal\n");
13 }
14 printf("length: %zu\n", strlen(attempt));
15 return 0;
16}strcmp says equal length: 7
Lendo uma linha com fgets
scanf("%s", buf) para no primeiro espaço e não faz ideia do tamanho de buf. Para ler uma linha inteira com segurança, use fgets(buf, sizeof buf, stdin): ele lê no máximo sizeof buf - 1 caracteres e acrescenta o terminador. Ele mantém o caractere de nova linha, que normalmente você quer remover:
1#include <stdio.h>
2#include <string.h>
3
4int main(void) {
5 char name[64];
6 if (fgets(name, sizeof name, stdin) == NULL) {
7 return 1;
8 }
9 name[strcspn(name, "\n")] = '\0'; // chop the newline
10 printf("Hello, %s!\n", name);
11 return 0;
12}strcspn(name, "\n") devolve o índice da primeira quebra de linha (ou o tamanho da string, se não houver nenhuma), então escrever '\0' ali a remove de forma limpa.
Principais conclusões
Uma string em C é um array de
charterminado em'\0'; ela precisa de tamanho + 1 bytes.Compare com
strcmp(a, b) == 0, nunca com==. Meça comstrlen(que não conta o terminador).Prefira as funções com limite:
snprintfem vez destrcpy/strcat, efgetsem vez descanf("%s").
Quiz da aula
5 perguntas · aprovação com 4 acertos · até 50 XP
Ao passar, você conclui a aula e mantém sua sequência. As perguntas erradas voltarão em sessões de revisão.
Pratique: escreva código em C
Estes exercícios rodam de verdade. Escreva o programa, clique em “Executar testes” e leia o que o compilador informa: aprender a ler as mensagens do compilador é metade do aprendizado de C.
Conte as vogais
Leia uma linha de texto (use fgets) e imprima quantas vogais ela contém - a, e, i, o, u, maiúsculas ou minúsculas.
Para Hello World, imprima 3.
- Hello World
- Maiúsculas
- Sem vogais
Seu código é compilado com gcc 14 (-Wall -Wextra) e executado no Compiler Explorer (godbolt.org), um serviço público gratuito.
Inverta uma palavra
Escreva void reverse(char *s), que inverte uma string no próprio lugar (troque os caracteres das duas pontas em direção ao meio). A main lê uma palavra e a imprime invertida.
Para stressed, imprima desserts.
- stressed
- Tamanho ímpar
- Um único caractere
Seu código é compilado com gcc 14 (-Wall -Wextra) e executado no Compiler Explorer (godbolt.org), um serviço público gratuito.
Dúvidas sobre esta lição
Travou em algum ponto? Pergunte. Descobriu algo? Compartilhe. Explicar também é uma ótima forma de aprender.
Carregando publicações…