Programar em C++/Manipulando strings: diferenças entre revisões

[revisão pendente][revisão pendente]
Conteúdo apagado Conteúdo adicionado
m <source> -> <syntaxhighlight> (phab:T237267)
 
Linha 35:
Por exemplo, para declarar um espaço na memória que contenha 20 caracteres fazemos:
 
<sourcesyntaxhighlight lang=cpp>
char dados[20];
</syntaxhighlight>
</source>
 
Este é o estilo de strings usado pela linguagem C pura. Para manipular este tipo de string é preciso ter certo cuidado, pois a matriz sempre tem um tamanho definido e caso façamos um acesso a um endereço fora da matriz invadiremos outras áreas de memória que não temos como definir o que são, e portanto poderemos fazer o programa parar de funcionar, em muitos sistemas pode também haver danos aos outros programas e até mesmo ao próprio sistema operacional, porém em sistemas operacionais mais sofisticados como o GNU/Linux, que possuem gerenciamento de memória com proteção de memória, apenas o programa que causou a falha irá parar de funcionar.
Linha 45:
No estilo C++, como era de se esperar, as strings são objetos, eles podem ser criados facilmente através da biblioteca padrão referenciada pelo arquivo de cabeçalho <string>. As strings são objetos com recursos que permitem manipular os seus caracteres com as funcionalidades das funções da linguagem C e mais algumas características próprias possibilitadas pela orientação a objetos.
 
<sourcesyntaxhighlight lang=cpp>
// listandoCodigoASCII.cpp
 
Linha 71:
 
} //end main
</syntaxhighlight>
</source>
 
== Funções de caracteres úteis. ==
Linha 81:
'''tolower()''' – (to+lower) o mesmo comportamento que toupper(), porém com o resultado em minúscula.
 
<sourcesyntaxhighlight lang=cpp>
#include <iostream>
#include <cctype>
Linha 107:
return 0;
}
</syntaxhighlight>
</source>
 
Funções que verificam o caractere. Estas funções recebem apenas um argumento, o caractere e retornam um valor booleano.
Linha 135:
A primeira coisa a notar quando criamos strings em C++ é a maneira de criá-las, a classe disponibiliza uma série de construtores:
 
<sourcesyntaxhighlight lang=cpp>
1 string ( );
2 string ( const string& st );
Linha 142:
5 string ( const char * ps );
6 string ( size_t n, char ch );
</syntaxhighlight>
</source>
 
Isto torna possível, basicamente, criar string de seis maneiras diferentes:
Linha 155:
Quando manipulamos strings, podemos fazê-lo com operadores, como por exemplo "+", "+=", "<<", etc... Isto torna o código um pouco mais intuitivo, vejamos os operadores:
 
<sourcesyntaxhighlight lang=cpp>
1 operator=
2 operator[]
Linha 162:
5 operator<<
6 operator>>
</syntaxhighlight>
</source>
 
Que representam as operações:
Linha 175:
Apenas com estas poucas informações já é possível operar strings com bastante flexibilidade e de uma maneira muito intuitiva, vejamos alguns exemplos:
 
<sourcesyntaxhighlight lang=cpp>
string a = ("Alice e Beto gostam de "),
b = ("chocolate."),
Linha 186:
cout << a + d << endl;
cout << a + e << endl;
</syntaxhighlight>
</source>
 
Estas operações resultam em:
 
<sourcesyntaxhighlight lang=text>
Alice e Beto gostam de chocolate.
Alice e Beto gostam de doce de leite.
Alice e Beto gostam de pipoca.
Alice e Beto gostam de doce de leite.
</syntaxhighlight>
</source>
 
=== Exemplos de como manipular strings em C++ ===
''' erase '''
A função membro erase elimina parte de uma string. Os parâmetros passados para a função são a posição inicial e o número de caracteres a ser excluído. Veja um exemplo de uso abaixo:
<sourcesyntaxhighlight lang=cpp>
#include<iostream>
using std::cout;
Linha 221:
return 0;
}
</syntaxhighlight>
</source>
 
== Comparando formas de operar strings em C e C++ ==
Linha 231:
'''strlen()''' – (str=string + len=length)- aceita um argumento que pode ser um array (uma cadeia) de caracteres, um ponteiro (que aponta para um array de caracteres) ou uma string literal. retorna um número inteiro que representa o número de caracteres, não incluindo o caractere "null":
 
<sourcesyntaxhighlight lang=cpp>
int len;
len = strlen("Jeff") // a extensão é 4
Linha 238:
char name[80] = "Devvie";
len = strlen(name); // a extensão é 6
</syntaxhighlight>
</source>
 
No c++ temos duas funções similares na classe string que são o lenght() e size(). Estas funções não tem argumentos pois reportam as informações sobre o objeto a quem pertencem, ambas retornam um inteiro que representa o tamanho das strings:
 
<sourcesyntaxhighlight lang=cpp>
string s = "Jeff Kent";
cout << s.length(); // mostra: 9
cout << s.size(); // também mostra: 9
</syntaxhighlight>
</source>
 
=== Copiando strings ===
Linha 252:
Se tentássemos copiar strings desta maneira
 
<sourcesyntaxhighlight lang=cpp>
char* target = "Jeff Kent";
char src[80] = "Micaela";
target = src;
</syntaxhighlight>
</source>
 
O que acontecia é que era a cópia do endereço de src para o ponteiro e não os caracteres que estão dentro da matriz.
Linha 264:
* O segundo é a frase a ser copiada e pode ser um array, um ponteiro ou um string literal
 
<sourcesyntaxhighlight lang=cpp>
char* target = "Jeff Kent";
char src[80] = "Micaela";
strcpy(target, src);
</syntaxhighlight>
</source>
 
Note que esta operação é muito arriscada visto que, quando criamos target, a quantidade de caracteres que foi reservada para a string era de 9 caracteres mais o caractere nulo no final, se fizermos uma cópia de uma string com mais de 9 caracteres para este endereço, representado por target, ele fatalmente causará uma violação de endereço.
Linha 274:
Porém em C++ podemos atribuir o valor de uma variável para outra da classe string da forma:
 
<sourcesyntaxhighlight lang=cpp>
string target = "Jeff Kent";
string src = "Micaela";
target = src;
</syntaxhighlight>
</source>
 
Agora, reflitamos no que significa estas operações: Em primeiro lugar "string" não é um tipo primitivo de dado, é uma classe, portanto é um tipo de dado mais "inteligente", uma das características dos objetos string é que eles são redimensionáveis, ou seja, quando atribuímos a uma string um dado maior que seu espaço interno de armazenamento ela aumenta o seu espaço interno para comportar o novo dado. Outra característica é que a operação "=" para a string é uma operação de atribuição de conteúdo, de forma que a string copia a outra quando usamos este operador e não apenas o ponteiro que referência o endereço da string.
Linha 286:
'''strcat()''' – (string+concatenate) – une duas frases. Recebe 2 argumentos, a frase primária – o ponteiro para esse array.
 
<sourcesyntaxhighlight lang=cpp>
char target[80] = "Jeff";
char* source= " Kent";
strcat(target, source);
cout << target; // Mostra "Jeff Kent"
</syntaxhighlight>
</source>
 
Deve-se observar que strcat é, potencialmente, uma das rotinas mais '''perigosas''' do C, por um motivo bem simples: a string de destino deve ser pre-dimensionada, e deve ter espaço suficiente para receber a string de origem. Um pequeno programa como:
 
<sourcesyntaxhighlight lang=cpp>
char target[13] = "Regras do C!";
char* source = " Mas pode dar resultados imprevisiveis";
strcat(target, source);
</syntaxhighlight>
</source>
 
Escreverá bytes em regiões da memória que não foram previamente alocadas para a string. Em c++, este problema é resolvido pelo uso de objetos string.
Linha 305:
Ao estilo de c++ podemos fazer.
 
<sourcesyntaxhighlight lang=cpp>
string target = "Regras do C++!\n";
string source = " Geralmente não dão resultados imprevisiveis.\n";
Linha 311:
cout << target; // Mostra: Regras do C++!
// Geralmente não dão resultados imprevisiveis.
</syntaxhighlight>
</source>
 
Isto porque a classe string prevê o uso do operador "+=" de concatenação e nele está embutido um código de verificação de espaço e realocação do mesmo para string, caso seja necessário.
Linha 319:
se fizessemos
 
<sourcesyntaxhighlight lang=cpp>
char str1[80] = "Devvie Kent";
char str2[80] = "Devvie Kent";
Linha 326:
else
cout << "The two C-strings are not equal";
</syntaxhighlight>
</source>
 
o que acontecia é que estariamos a comparar os endereços e não os valores
Linha 332:
temos a função strcmp (string+compare) (tem 2 arguentos. retornar 0 se forem iguais)
 
<sourcesyntaxhighlight lang=cpp>
char str1[80] = "Devvie Kent";
char str2[80] = "Devvie Kent";
Linha 339:
else
cout << "The two C-strings are not equal";
</syntaxhighlight>
</source>
 
esta comparação pode ser resultar em negativo e positivo e isso tem a ver com o jogo de caracteres na tabela ascII. aqui vai um resumo
Linha 359:
Em C++ podemos comparar duas strings através da função membro da classe string: compare(), existem os seguintes formatos (assinaturas) para a função:
 
<sourcesyntaxhighlight lang=cpp>
1 int compare ( const string& str2 ) const;
2 int compare ( const char* szc ) const;
Linha 366:
5 int compare ( size_t pos1, size_t n1, const string& str2, size_t pos2, size_t n2 ) const;
6 int compare ( size_t pos1, size_t n1, const char* szc, size_t n2) const;
</syntaxhighlight>
</source>
 
A função permite os seguintes modos de operação, respectivamente:
Linha 380:
 
Se estiver comparando duas strings uma outra opção, ainda mais natural, é utilizar os operadores de comparação < e ==.
<sourcesyntaxhighlight lang=cpp>
using namespace std;
 
Linha 391:
else
cout << "A palavra " << str1 << " vem depois de " << str2 << endl;
</syntaxhighlight>
</source>
 
=== Convertendo C-string e número ===
Linha 399:
'''atoi''' (acrônimo para "ASCII to integer") recebe um argumento – c-string) e retorna o inteiro que a c-string representa. Não verifica se o argumento pode ser convertido:
 
<sourcesyntaxhighlight lang=cpp>
int num = atoi("7654");
</syntaxhighlight>
</source>
 
Programa exemplo:
 
<sourcesyntaxhighlight lang=cpp>
#include <iostream>
#include <cstdlib> // necessário para atoi
Linha 440:
return 0;
}
</syntaxhighlight>
</source>
 
Neste exemplo temos a vantagem de o usuário inserir um dígito para o array de caracteres em vez de um inteiro, para evitar um "run-time error" ou "garbage data" que aconteceria se a entrada fosse não numérica.
Linha 448:
Em C++ usamos objetos da classe stringstream (biblioteca sstream.h) para armazenar temporariamente os caracteres, depois usamos o operador ">>" para converter os caracteres em número, bastando para isto criar a variável no formato que desejamos receber o número. Mais uma vez temos o uso do poliformismo para resolução de um problema comum de programação, a operação do ">>" é diferente para cada tipo de dado, selecionada automaticamente pelo compilador de acordo com o tipo de dado da variável destino.
 
<sourcesyntaxhighlight lang=cpp>
string name = "123";
stringstream sst;
Linha 454:
sst << name << endl;
sst >> i;
</syntaxhighlight>
</source>
 
Os passos acima armazenam o valor <font color=blue>123</font> na variável "i", todo processo de conversão é feito pelo operador ">>".