Escolar Documentos
Profissional Documentos
Cultura Documentos
Escrevendo em C
Introdução as strings: o que são, como declarar e
inicializar – O Operador \0
Após nosso estudo sobre vetores e das noções sobre ponteiros, vamos usar esses conhecimentos
obtidos em nosso curso online de C.
Tente achar um programa que não tenha nada escrito. Que não seja necessário ler ou informar
alguma letra ou palavra.
Até nas calculadoras temos que inserir caracteres (+, -, *, % etc).
Essa seção é totalmente dedicada a escrita, suas bibliotecas, funções, funcionamento e detalhes.
Sim, vamos aprender a escrever em C, nesta seção de nossa apostila.
Por exemplo, para escrever “ C Progressivo”, seria necessário declararmos 13 caracteres e preenchê-
los um por um, o que, obviamente é inviável, pois daria muito trabalho.
Imagine escrever textos longos com variáveis do tipo char puras.
Para contornar isso, o C trata vetores de caracteres de uma forma muito especial, com certas
‘regalias’, detalhes e opções, em relação aos outros tipos de vetores.
Aqui, porém, vale uma ressalva muito importante que geralmente os programadores C iniciantes
esquecem: o caractere delimitador - \0 – também fará parte da string.
Ou seja, ele conta no número de caracteres, no tamanho da String.
Então, para declarar uma string que vai armazenar “C Progressivo”, temos que fazer:
char curso_de_C[14];
Logo, sempre que formos declarar uma string, temos que levar em consideração no seu tamanho o
caractere delimitador. No exemplo que demos, temos que declarar uma string que armazene 14
caracteres ou mais.
Que lembra o que fazíamos nos vetores. Desse jeito, o C vai alocar o número exato de caracteres
necessários, que no caso é 14 (13 para nossa frase mais 1 para o \0).
Outra possibilidade de carga automática, onde o C aloca o número certo de caracteres, é através de
ponteiros. Lembra que dissemos que o nome do vetor é, na verdade, um endereço de memória?
Endereço do primeiro elemento do vetor?
Podemos então inicializar uma string através de um ponteiro para o tipo char:
char *curso = “C Progressivo”;
Quando formos estudar e criar as funções da biblioteca string.h, que nos fornece diversas opções
para trabalhar com strings, vamos usar bastante os conceitos de ponteiros.
Por fim, podemos inicializar as strings da maneira mais ‘trabalhosa’, que é caractere por caractere
onde,
mais uma vez, o C colocar o delimitador de string \0 na última posição:
char curso[14] = {‘C’, ‘ ‘, ‘P’, ‘r’, ‘o’, ‘g’, ‘r’, ‘e’, ‘s’, ‘s’, ‘i’, ‘v’, ’o’};
Como nosso vetor tem 20 posições, podemos preencher, no máximo, até a posição 18.
Como usamos somente a frase “C Progressivo”, de 13 caracteres, o caractere \0 será o 14º caractere.
Vamos usar o primeiro laço for para imprimir todos os caracteres da string ‘curso’.
Note que o C imprime todos os caracteres antes do \0, e depois dele, nenhum.
O segundo laço for faz com que nossa variável auxiliar inicie na posição 0 da string e vá até a posição
em que encontra o \0. Quando encontra, o laço para e mostramos em que posição encontrou o
delimitador.
#include <stdio.h>
// Curso C Progressivo: www.cprogessivo.net
// O melhor curso de C! Online e gratuito !
// Artigos, apostilas, tutoriais e vídeo-aulas sobre
// a linguagem de programação C !
int main(void)
{
char curso[20] = "C Progressivo";
int count;
}
Na verdade, existem maneiras bem mais simples de se exibir strings, que você aprenderá no próximo
tutorial de nosso curso online de C.
Decidimos ensinar dessa maneira para você saber o que ocorre por debaixo dos panos, ver o
caractere delimitador atuando de verdade.
Mas só mostrar não adianta muita coisa, geralmente é preciso receber strings do usuário.
Afinal, quem nunca forneceu o nome pra ficar no ranking daquele jogo, data e local de nascimento,
nome dos pais e outros tipos de texto?
Nesse tutorial sobre strings em C, vamos ensinar como receber textos do usuário.
%s
Antes de iniciar nosso estudo das funções que recebem e lêem strings, vamos apresentar o %s.
Você deve se lembrar que usamos %d para representar números inteiros, %f para números decimais
e %c para caracteres.
Há um porém com a leitura de strings e um problema com a função scanf para strings.
O porém é o seguinte: lembra que repetimos, exaustivamente, que o nome de um vetor nada mais é
que o endereço de memória do primeiro elemento do vetor?
Lembra que dissemos também no tutorial de C passado, sobre a definição de strings, que strings são
um vetor de caracteres com um caractere delimitador \0 no final?
E por fim, lembra que, para armazenar dado em uma variável, na função scanf() nós sempre
passamos o endereço da variável ( &variável)?
Se você conseguiu ver onde chegamos, notará que para receber uma string do usuário através da
funçãoscanf(), não é necessário colocar o operador &, pois o nome da string em si já é um endereço
de memória.
Criamos duas strings, optamos por colocar 20 caracteres em cada, como temos que ter o caractere
delimitador, então declaramos o vetor de caracteres com 21 elementos cada, um pro nome e outro
pro sobrenome.
#include <stdio.h>
// Curso C Progressivo: www.cprogessivo.net
// O melhor curso de C! Online e gratuito !
// Apostila online, tutorial completo sobre
// a linguagem de programação C !
int main()
{
char nome[21], sobrenome[21];
Pois bem, digite um nome composto no ‘nome’ ou no ‘sobrenome’. Ou seja, um nome com espaço em
branco.
A scanf() vai simplesmente cortar seu nome composto. Essa função pega tudo até encontrar um
espaço em branco, caractere new line \n, tab ou ENTER.
Para corrigir isso, o C tem uma função especial e bem mais simples para receber strings do usuário, a
função gets().
Como receber strings do usuário com a
função gets()
gets vem de get string. Como sempre, algo bem óbvio e de fácil memorização.
Para usar a função gets(), é bem simples, basta passar uma string como argumento.
A sintaxe é:
gets( nome_da_string );
Mais uma vez, nunca use & quando for armazenar uma string. Isso não é necessário, pois string é um
vetor, e o nome do vetor já é um endereço, e um endereço é o operador & seguido do nome da
variável.
Esse aplicativo é bem simples, e certamente você fará sem maiores problemas.
Porém, existe uma pequena casca de banana nele, que colocamos de propósito.
Vimos que a função scanf() pega tudo até aparecer o primeiro espaço em branco, e pára antes dele.
Já a gets() não, ela pega tudo até aparecer uma new line \n, inclusive nada. Ou seja, se você der um
ENTER, a gets() vai armazenar esse enter na string.
O problema é que a função gets() vai pegar o que está armazenado nesse buffer e vai armazenar o
que estiver lá na string de data de nascimento!
E como evitar isso? Ora, é só apagar esse ENTER que está no buffer, usando o fflush(stdin) caso use
Windows, ou __fpurge(stdin) caso seja abençoado e use Linux.
int main(void)
{
char nome[31], sobrenome[31], nascimento[11];
int idade;
printf("Nome: ");
gets(nome);
printf("Sobrenome: ");
gets(sobrenome);
printf("Idade: ");
scanf("%d", &idade);
fflush(stdin);
Um exemplo disso, que já mostramos neste mesmo artigo de nossa apostila, foi o da scanf(), que só
lê até o primeiro espaço, pois isso é a característica padrão da função.
É característica padrão, e não obrigatória. Ou seja, embora poucos saibam, é possível alterar o
funcionamento da scanf(). Por exemplo, se quisermos ler strings que tenham espaço, nós temos que
dizer isso dentro da função.
Vamos dizer para a scanf() parar de pegar nossa string somente quando encontrar um caractere de
NEW LINE (um enter). Para isso, usamos o operador: [^\n]
Logo, nosso código da scanf() para ler strings com espaços e armazenar na variável "str" é:
scanf ( "%[^\n]", str);
Podemos ainda limitar o tamanho de nossa string, basta colocar um numero inteiro ao lado do %,
representando o número de caracteres máximo, o que é uma excelente prática, pois essa função
pode ocasionar problemas na memória, caso você estoure os limites da string.
Por exemplo:
scanf ( "%256[^\n]", str);
A função gets() peca nesse quesito, de tamanho da string, pois podemos digitar mais caracteres do
que a string alocou de memória, e "quebraríamos" o programa por conta de um overflow.
Algumas pessoas relatam problemas de usar ela em um ambiente Linux.
Como dissemos, elas podem ocasionar problemas na memória, onde é fácil extrapolarmos o limite da
memória, encerrando o programa por isso. Portanto, se quiser usar uma função de maneira segura,
em programas profissionais, evite a gets(). Use fgets() ou scanf() sempre com litadores de new line e
tamanho da string.