Italo Info


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.