Conjuntos de caracteres (Strings)
Através da linguagem C, é possível manipular dados que representam uma sequência de caracteres. Eu me refiro ao tipo string (array de caracteres - chars). Por exemplo, veja o programa abaixo:
#include <stdio.h>
#include <string.h>
int main() {
char palavra[30];
int tam;
printf( "Informe uma palavra: " );
scanf( "%s", palavra );
tam = strlen( palavra );
if ( tam > 0 )
printf( "\nA primeira letra da palavra eh: %c", palavra[0] );
else printf( "\nVoce nao digitou uma palavra!" );
return 0;
}
No programa acima é declarado um array de chars para armazenar o conjunto de caracteres (string). Logo após a declaração de variáveis, o programa solicita que o usuário informe uma palavra e a armazena na variável de nome palavra. Em seguida, o programa calcula a quantidade de caracteres da string informada utilizando a função strlen (str de string e len de length - tamanho). Caso o usuário não tenha digitado um texto vazio, a primeira letra da palavra informada é impressa. Perceba que não é necessário passar a variável "palavra" com & no scanf.
Apesar de simples, esse exemplo tem uma pequena limitação! Caso você digite uma string com espaços, apenas a primeira palavra da string é lida e o restante ignorado. Logo, se digitar: "abc def", na variável "palavra" é armazenada apenas "abc".
Como uma string é armazenada
Uma string é armazenada como um array de chars. Por exemplo: A palavra "amor" fica armazenada da seguinte forma:
Caracteres | a | m | o | r | \0 |
---|---|---|---|---|---|
Indice | 0 | 1 | 2 | 3 | 4 |
Preste atenção ao vetor string utilizado para armazenar a palavra amor. Repare o caractere \0 (Caractere nulo) marca o final da string. Se fosse a fraze "Meu amor!" ficaria armazenado conforme a seguir:
Caracteres | M | e | u | a | m | o | r | ! | \0 | |
---|---|---|---|---|---|---|---|---|---|---|
Indice | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
Veja abaixo, um programa que solicita que o usuário informe uma string (a leitura é feita através da função scanf) e mostra se a string que o usuário digitou é igual a palavra "amor":
#include <stdio.h>
#include <string.h>
int main() {
char palavra1[30];
char palavra2[30];
strcpy( palavra1, "amor" );
printf( "Informe uma palavra: " );
scanf( "%s", palavra2 );
if ( strcmp( palavra1, palavra2 ) == 0 )
printf( "\nVoce digitou a palavra amor" );
else printf( "\nVoce nao digitou a palavra amor" );
return 0;
}
Veja o próximo exemplo que trata-se de um programa que pede que o usuário digite duas strings e informa se a primeira é igual, menor ou maior que a segunda. Ex: A palavra cadeira é menor que a palavra ovo, pois, a primeira letra da palavra cadeira (que é 'c'), é menor que a primeira letra da palavra ovo (que é 'o').
#include <stdio.h>
#include <string.h>
int main() {
char palavra1[30];
char palavra2[30];
int cmp;
printf( "Informe uma palavra(1): " );
scanf( "%s", palavra1 );
printf( "Informe uma palavra(2): " );
scanf( "%s", palavra2 );
cmp = strcmp( palavra1, palavra2 );
/* ATENCAO: a funcao strcmp permite que duas strings
seja verificadas em ordem alfabética se a primeira eh
maior, menor ou igual a segunda (conforme a ordenacao) */
if ( cmp == 0 )
printf( "\nA primeira palavra eh igual a segunda." );
else if ( cmp < 0 )
printf( "\nA primeira palavra eh maior que a segunda." );
else printf( "\nA primeira palavra eh menor que a segunda." );
return 0;
}
Abaixo um programa que concatena duas strings e mostra o resultado. Para concatenação, é utilizada a função strcat conforme a seguir:
#include <stdio.h>
#include <string.h>
int main() {
char palavra1[60];
char palavra2[30];
strcpy( palavra1, "Oi! meu nome eh " );
strcpy( palavra2, "Italo" );
strcat( palavra1, palavra2 );
printf( "%s", palavra1 );
return 0;
}
Substituindo scanf
Agora, vamos resolver a limitação da string lida ter ignorada a parte após o primeiro espaço. Para tanto, vamos utilizar no lugar de scanf, a função fgets que pode ler da saída padrão ou do fluxo de dados de um arquivo. Nesse caso, utilizaremos a saída padrão como acontece com a função scanf.
Vamor entender a função fgets. Ela recebe 3 argumentos. O primeiro é a variável string. O segundo é o quantidade máxima de memória alocada para a string. No exemplo acima, o tamanho máximo é o tamanho do array de caracteres que corresponde a variável string. E o terceiro argumento é um fluxo de entrada de dados que pode ser a saída padrão ou um tipo arquivo que será visto mais pra frente nesse curso.
Veja o programa abaixo:
#include <stdio.h>
#include <string.h>
int main() {
char texto[30];
int tam;
printf( "Informe uma string: " );
fgets( texto, 30, stdin );
printf( "String lida: (%s)\n", texto );
return 0;
}
A função fgets recebeu como primeiro argumento a variável string "texto", o segundo argumento foi o tamanho do array (no caso 30) e o terceiro argumento, a palavra reservada stdin que referencia a entrada padrão.
O programa funciona! Resolve a limitação da leitura de strings com scanf. No entanto, há um outro problema, esse modo de leitura da string insere ao final da string o caractere que corresponde a tecla do enter: '\n'. Assim a string lida é diferente da string com o mesmo conteúdo, mas sem um pula linha no seu final. Logo, para resolver o problema, basta substituir o último caractere da string que é o pula linha pelo valor '\0' que marca o final da string. Veja a seguir:
#include <stdio.h>
#include <string.h>
int main() {
char texto[30];
int tam;
printf( "Informe uma string: " );
fgets( texto, 30, stdin );
texto[ strlen( texto )-1 ] = '\0';
printf( "String lida: (%s)\n", texto );
return 0;
}
Agora sim! O programa funciona porque strlen retorna o tamanho da string e, como o array começa na posição 0, a posição do último caractere (o pula linha), corresponde ao tamanho da string menos um. Assim, é atribuído '\0' à última posição da string. No caso da string estar vazia (caso do usuário pressionar apenas um enter), um caractere '\n' foi inserido e, nesse caso a string tem tamanho 1. Logo, a posição do caractere de pula linha é 0 e é nessa posição que o '\0' é colocado. Assim, o exemplo funciona até para o caso do usuário digitar somente um enter.
Como será visto mais adiante na aula sobre funções, é possível criar uma função e chamá-la no programa principal. Podemos criar uma função para remover o pula linha da string da seguinte forma:
#include <stdio.h>
#include <string.h>
void remove_enter( char* str ) {
str[ strlen( str ) - 1 ] = '\0';
}
int main() {
char texto[30];
int tam;
printf( "Informe uma string: " );
fgets( texto, 30, stdin );
remove_enter( texto );
printf( "String lida: (%s)\n", texto );
return 0;
}
Exercícios
1) Faça um programa que leia uma string e verifique se a primeira letra da string lida é igual a "C"
2) Faça um programa que leia uma string e verifique se a primeira letra é igual a ultima.
Atenção: É necessário verificar o tamanho da string que deve ser maior ou igual a 1.
3) Faça um programa que leia uma string, inverta os valores da primeira letra e a ultima e mostre a string alterada.
Atenção: É necessário verificar se a string lida tem tamanho maior ou igual a 2.
Dica: para inverter o valor de duas variáveis, por exemplo, de nome (a) e (b), utilize uma variável auxiliar (aux) como a seguir:
aux = a;
a = b;
b = aux;
4) Faça um programa que verifique se uma string é palíndromo. Isto é, uma palavra é dita palindromo se a primeira letra é igual a ultima, a segunda é igual a penultima e, assim, sucessivamente.
Exemplo: São palíndromos as palavras: ovo, erre, abcba, ijkji, ijji. Não são palíndromos as palavras: ova, erra, abcea.