Namespaces e Strings em C++

Namespaces

Conforme já visto em aula, para usar os recursos de entrada e saída da biblioteca iostream em C++, é preciso incluir o comando using namespace std.

Este comando serve para definir um "espaço de nomes", ou namespace. Um namespace permite a definição de estruturas, estruturas, classes, funções, constantes, etc, que estarão vinculadas a ele. Isso evita duplicidade com, por exemplo, outras implementações com nomes semelhantes. Por definição, a linguagem C++ utiliza o namespace std para definir todas as funções da biblioteca padrão.

Se não utilizarmos o comando using..., será necessário especificar explicitamente o namespace utilizado, como por exemplo:

#include <iostream>

int main()
{
	std::cout << "Exemplo de saída na tela" << std::endl;

	...
}

É possível também o próprio usuário definir os seus próprios namespaces, mas isso é um tópico avançado que não será abordado agora. Também existem situações onde não é interessante utilizar um namespace, como veremos mais adiante.

Strings em C++

A linguagem C++ oferece uma série de facilidades para a construção de programas mais longos, especialmente através da biblioteca STL, como será visto mais adiante. Um desses recursos é a manipulação de strings, ou cadeias de caracteres. Em C, strings são implementadas através de vetores de caracteres, cujo último elemento deve ser um caractere nulo (\0).

Já em C++ o usuário pode empregar a palavra string para declarar uma string de tamanho variável. Porém, deve ser incluído o header string. A partir da declaração, a utilização de strings é simples.

Inicialização e atribuição de strings

O primeiro passo é declarar-se as variáveis desejadas, e inicializá-las se for o caso, como mostra o exemplo a seguir. Nesse exemplo, as variáveis nome1 e nome2 são inicializadas, mas nome3 não:

#include <iostream>
#include <string>		// Necessário para usar strings
using namespace std;

int main()
{
	string nome1("Fulano");		// Inicializa nome1
	string nome2("Beltrano");	// Inicializa nome2
	string nome3, nome4;		// Não inicializa nome3 nem nome4

	cout << "Os dois primeiros nomes são " << nome1 << " e " << nome2 << endl;
	nome3 = "Ciclano";		// Inicialização posterior de nome3
	nome4 = nome3;
	cout << "O terceiro e quarto nomes são " << nome3 << " e " << nome4 << endl;
}

Acesso a caracteres individuais de uma string

Assim como em C, C++ define o operador [..] para permitir o acesso a caracteres individuais dentro de uma string. Porém, C++ também define o operador at, que não permite o acesso a posições inválidas - observe o exemplo abaixo:

#include <iostream>
#include <string>

using namespace std;

int main()
{
	string nome1("Fulano");		// Inicializa nome1
	string nome2("Beltrano");	// Inicializa nome2
	string nome3, nome4;		// Não inicializa nome3 nem nome4

	nome1[0] = nome2[0];		// Troca para "Bulano"
	nome2[7] = 'a';			// Troca para "Beltrana"
	cout << "Os dois primeiros nome são: " << nome1 << " e " << nome2 << endl;

	// Sem usar string.at:
	cout << "O caractere 10 do segundo nome é: " << nome2[10] << endl;	// ERRO! Não existe o caractere 10!

	// Usando string.at:
	cout << "O caractere 10 do segundo nome é: " << nome2.at(10) << endl;	// ERRO, mas aborta o programa dessa vez
}

O que acontece quando a chamada nome2.at(10) é realizada ? O programa termina de forma anormal - na verdade, ele gera uma exceção, que pode ser tratada futuramente. A vantagem é que o programador não corre o risco de acessar memória inválida, o que frequentemente leva a resultados desastrosos em C!

Comparação de strings

Em C++, pode-se usar os operadores ==, !=, >, >= ou < para fazer comparações alfabéticas entre duas strings. Também pode-se empregar a função compare para retornar um valor numérico igual a 0, menor que 0 ou maior que 0, dependendo da relação de ordem entre as strings, da mesma forma que a função strcmp em C. Observe o programa abaixo:

#include <iostream>
#include <string>

using namespace std;

int main()
{
	string nome1("Fulano");		// Inicializa nome1
	string nome2("Beltrano");	// Inicializa nome2

	if(nome1 > nome2)
		cout << nome1 << " vem depois de " << nome2 << endl;
	else if(nome1 == nome2)
		cout << "Os nomes são iguais" << endl;
	else
		cout << nome1 << " vem antes de " << nome2 << endl;
}

Neste caso, irá aparecer na tela "Fulano vem depois de Beltrano".

Manipulando o tamanho de uma string

Como as strings em C++ têm tamanho variável, existem uma série de funções que podem ser utilizadas para controlar e manipular essa propriedade. Por tamanho variável, deve-se entender que uma string reserva uma certa quantidade de memória (sua capacidade), mas não necessariamente utiliza toda essa memória. Caso a string cresca mais do que a sua capacidade, então mais memória é reservada e assim por diante. A seguir apresenta-se as principais funções:

Veja a seguir um exemplo de utilização da função size():

#include <iostream>
#include <string>

using namespace std;

int main()
{
	string s1, s2("valor inicial"), s3[10];
	s1 = s2 + " copiado de s2";			// concatenacao e atribuicao
	cout << s1 << endl;
	for (int i=0; i<10; i++) cin >> s3[i];
	s1 += s3[0];
	cout << "tamanho de s2 é: " << s2.size();
	int sz= s2.size();
	for (int i=0; i<sz; i++) cout << s2[i] << " ";	// acesso a caracter
	cout << endl;
}

Outras operações

O guia de referência à biblioteca padrão C++ contém uma descrição completa de todas as operações sobre strings: veja aqui.