Aqui também a gente pode substituir caracteres.
Aqui de volta eu ponho 8 anos.
Eu posso, por exemplo,
remover todos os caracteres da posição 62 até o fim.
Eu posso substituir todos os espaços por um ponto.
Eu posso, por exemplo, encontrar o primeiro espaço
depois, o que eu estou fazendo aqui?
Ah sim, estou substituindo de fato na string "s"
todos os elementos de "x" por um ponto.
É isso? É isso.
Justamente, aqui ele faz a substituição como eu estava dizendo.
Ele vai encontrar a primeira situação, a primeira posição em "s"
uma posição em branco, vai armazenar essa posição em "x",
vai testar se "x" não é o tamanho máximo de todas as strings estanciadas,
que é provavelmente um atributo estático,
como só tem uma string "s" estanciada ele vai usar o tamanho de "s",
poderia ter utilizado o length ou algo assim, mas enfim,
ele vai reposicionar em "x", na posição "x", um ponto.
Ai ele vai encontrar o próximo elemento em branco,
a partir da posição "x + 1",
e vai ficar reposicionando todos so elementos.
E assim ele vai substituindo elemento a elemento.
Aqui ele continua fazendo uma substituição do mesmo formato,
só que uma máscara de substituição um pouco mais complexa,
com outros parâmetros um pouco mais peculiares, que vocês podem inferir pelo resultado dado.
Falando em resultado dado, o resultado está no grupo de slides 14,
está aqui a primeira máscara de substituição e a segunda máscara de substituição,
o resultado das substituições dadas lá no poema,
como se eu tivesse aqui "querendo fazer uma micro criptografia do poema" através de uma máscara dada.
Claro, isso é só um princípio elementar da coisa.
Aqui inserir caracteres em string.
Então eu tenho 4 strings como exemplo "s1", "s2", "s3" e "s4"
com esses valores que vocês estão enxergando aqui.
Estou imprimindo os valores.
E aqui eu posso "s1", a partir da posição 7, inserir o "s2".
Eu posso no "s3", a partir da posição 3, o "xx" de "s4".
E ai eu imprimo os resultados dessas inserções.
Eu posso também utilizar o insert para fazer inserções peculiares.
Ah, muito bem, continuando.
Aqui o resultado das inserções.
Eu também posso converter objetos string para variáveis de ponteiro de caractere.
Você tem que lembrar que objeto string gerencia um vetor de caractere,
ele não é o vetor de caractere.
Como a gente pode usar colchetes com objetos string, a gente tem a impressão que ele é o vetor de caracteres, mas ele não é.
O colchete dá essa impressão porque ele é um operador sobrecarregado,
justamente feito para usar em alto nível para dar essa impressão,
para você utilizar o objeto em alto nível.
Na prática, insisto, a string é um gerenciador de vetor de caracteres.
Bom, aqui eu tenho o objeto string "s" cuja essência é "STRINGS",
ou seja, o vetor de caracteres tem dentro dele isso aqui.
Aqui eu criei um ponteiro constante de caractere inicializado com nulo,
zero equivalente a nulo, nulo vale zero.
Aqui no tamanho eu estou pegando o tamanho da string, o comprimento da string.
Aqui eu estou criando um outro ponteiro de caractere,
só que aqui não é constante, não é constante porque eu estou alocando memória,
criando um vetor utilizando memória dinâmica.
Veja que eu crio ele aqui e depois deleto no final.
Muito bem.
Aqui eu tenhoo, perdão, aqui eu criei o vetor então,
eu aloquei memória.
Aloquei, inclusive, memória do mesmo tamanho do vetor de caracteres que está dentro de "s".
"s" tem um vetor de caracteres que é esse aqui,
tem um tamanho, e agora eu estou criando um vetor de caracteres que é compatível em tamanho com essência da string "s",
que é esse vetor aqui, insisto.
Aqui eu estou fazendo o que então?
Através do comando copy que existe dentro da própria string,
copiando a sua essência para esse vetor de caractere.
Então eu estou copiando a essência de "s", que é um vetor de caractere,
para esse vetor de caracteres "ptr2" que foi criado dinamicamente aqui.
E aqui na posição final de "ptr2" estou colocando um...
um elemento de término, um \0 na prática.
Aqui eu posso dizer que a string "s" é isso aqui.
A string "s" convertida para um ponteiro é,
ou seja, eu posso a partir da própria string "s"
acessar sua essência, que isso aqui,
através dessa função chamada c_str.
Isso permite eu ir lá e acessar o núcleo, o núcleo da string "s",
que é sempre um vetor de caractere, esse aqui inclusive.
Isso permite, então, através de um apontamento, você ir lá e ler o âmbito da coisa.
Agora sim, o "ptr2", que é um vetor de caractere criado dinamicamente,
tem um valor, ai eu imprimo aqui o conteúdo a partir do ponteiro inicial que é seu nome.
Como eu copiei o núcleo da string "s" para o "ptr2",
obviamente, ele também vai imprimir aqui "STRINGS".
Outra coisa que eu posso fazer aqui,
veja que eu tenho "ptr1", que é um ponteiro constante,
eu consigo através do data,
que é um comando, uma função membro de string, do tipo string,
então esse data eu consigo recuperar o que?
O primeiro ponteiro para o núcleo da string.
E aí, eu consigo a partir disso, imprimir caractere a caractere,
acessando diretamento o núcleo da string.
Aqui eu até estou utilizando um pouco de aritmética de ponteiros para fazer isso.
Bom.
Aqui eu estou deletando o ponteiro, aliás o vetor de caracteres, que eu criei dinamicamente lá em cima.
Bom isso aqui, pessoal, é só para saber que vocês tem meios, se precisar,
de acessar o núcleo de uma string, que é um vetor de caracteres.
Se você olha lá a nossa classe MinhaString,
o núcleo dele era justamente o pStr,
era um ponteiro de caractere que era núcleo da classe MinhaString,
que servia justamente para gerenciar um vetor de caracteres, aquele pStr na classe MinhaString,
Aqui na classe string não é diferente, eu tenho um núcleo
eu acesso esse núcleo, essa essência, ou através desse comando aqui
c_str ou através desse data.
Legal, está aqui a execução.
Iterador.
Eu posso usar em objetos tipos string um ponteiro de alto nível, por assim dizer, que é o iterator.
A gente já viu o iterator lá na nossa introdução a vector e a listas em aulas passadas.
Aqui ele vai usar mais ou menos o mesmo princípio.
Então eu tenho o iterator, inclusive constante.
Eu posso ter iterador não constante e constante.
O iterador constante permite ler e não modificar, obviamente.
O iterador normal permite ler e modificar a partir do iterador.
Como a gente dizia lá já em aulas passados, o iterator é um iterador de alto nível.
Aqui eu estou fazendo o iterator receber o início do vetor, da string,
dai eu vou dizer que eu vou imprimir o conteúdo de "s" usando o iterador,
enquanto o iterador, o "iterador1" né, não estiver no final da string,
ele vai imprimindo caractere a caractere, que é o que o iterador permite fazer.
Eu dizia que o iterator, o iterador, o "iterador1" no caso,
ele não deixa de ser um ponteiro de alto nível.
Ponteiro, para a gente acessar o conteúdo da coisa apontada
a gente usa o asterisco na frente, não usa?
Se eu quero acessar lá, acessar um vetor de caracteres usando um ponteiro
e eu quero enxergar aquele caractere em específico,
eu posso então usar o asterisco ponteiro para acessar o conteúdo.
Isso já conteúdo sabido e batido de disciplinas anteriores.
Aqui é similar.
Como o iterador é um ponteiro de alto nível,
ele usa a mesma lógica, ele vem e coloca o asterisco na frente, permite acessar o conteúdo apontado enfim.
Na verdade, na verdade,
isso aqui é um operador asterisco sobrecarregado na classe iterator
que gera esse efeito de recuperar conteúdo do elemento apontado.
Na prática é um operador sobrecarregado que está permitindo fazer essa arte.
Mas para quem está enxergando em alto nível, enfim,
o que está enxergando aqui gente,
é como se fosse um ponteiro que eu estou acessando conteúdo do ponteiro e colocando o asterisco na frente,
porque é assim que a gente faz para acessar conteúdo de elemento apontado.
Mas insisto mais uma vez, isso é só uma estratégia de alto nível
de quem implementou essa classe aqui, sobrecarregando o operador asterisco para criar esse efeito.
Muito bem.
Eu faço o iterador apontar para o próximo elemento da string "s",
imprimo o próximo elemento, e assim ele vai até chegar no final.
Muito bem, muito legal.
Está ai o resultado da coisa,
aqui foi impresso caractere a caractere obviamente,
através do iterador.
Processamento de strings em streams.
Então aqui, aqui eu coloquei na mesma linha.
Às vezes isso aqui pode dar erro se colocar na mesma linha, depende do compilador.
Às vezes tem compilador que vai exigir que vocês façam isso aqui,
vai exigir que vocês coloquem em linhas distintas.
como estou fazendo nesse preciso momento.
Está aqui a função main.
Aqui eu criei um novo objeto que é "StringSaída",
que é de um tipo que vocês não conhecem ainda.
É um output string stream, é um fluxo de saída string stream.
Onde que está esse cara aqui?
Vamos ver, incluiu iostream, ok.
Usando os comandos de processamento que interessam.
Incluiu string.
Ah sim, agora incluiu sstream,
fluxo para strings.
Eu tenho para entrada e saída, eu tenho fluxo para arquivo, parece razoável ter fluxo para strings.
Que é o que está acontecendo aqui.
Aqui eu criei o "s1", "s2", "s3", "s4" e "s5" que tem conteúdos.
"Saída de diversos tipos de dados
usando objeto ostringstream: double: int: endereço int:".
Essa frases aqui que explicam o exemplo,
servindo para argumentar cada uma dessas strings aqui.
Ainda eu criei um double, que é um float grandão por assim dizer.
tem esse valor, criei um inteiro que tem esse valor ali.
E aqui eu estou colocando no "StringSaida", veja que não é o cout ainda,
estou colocando no "StringSaida", uma espécie de buffer portanto,
O "s1", "s2", "s3", que são o que? Que são strings.
Mas também estou colocando o "d", então um número que está sendo convertido para uma string,
estou estou colocando o "s4" que já era string,
estou colocando o "i" que era um número e está sendo convertido para string,
estou colocando o "s5" que já era string,
e estou colocando o endereço de "i" que também está sendo convertido para string.
Estou pegando esses elementos que são de tipos diversos
e estou convertendo tudo para string e jogando nesse buffer aqui
que é um fluxo de saída no formato string.
Daí o que que é legal?
Legal que depois que eu converti tudo e armazenei no buffer,
eu posso numa pegada só, ir lá e imprimir no cout e usando o comando c_str do próprio objeto em questão.
Posso inclusive ir lá e colocar mais coisa no StringSaida e daí e reimprimir.
Bom aqui onde eu coloquei executando vocês podem executar esse código em casa para testar essa solução.
Isso é muito legal para você fazer log, por exemplo.
O que que é o log?
É o registro de atividades que está acontecendo no sistema.
Você quer armazenar o que está acontecendo no sistema através de textos, por exemplo,
por exemplo passei aqui, passei ali,
estou na posição tal do código, aconteceu isso no código,
você quer armazenar essa informações no registro, no log,
sem interferir muito na execução do código,
você pode usar um buffer desse.
Você pode usar um objeto como , por exemplo, log do tipo ostringstream e ir armazenando,
e só no final da execução você pega aquele conteúdo armazenado e joga no cout
ou até num arquivo de fluxo.
Muito bem.
Exercícios.
No projeto que desenvolvemos antes em sala, o das universidades,
utilize a classe predefinida string em vez de vetores de caracteres ou de até de um objeto de MinhaString.
Pessoal, vou encerrar a aula por aqui, mesmo porque já são 12h20.
Espero que tenham gostado da aula.
Essa aula até não precisaria de uma explicação, de um vídeo igual esse,
porque a maior parte do conteúdo são auto compreensíveis,
mas sempre tem um detalhezinho ou outro que é peculiar,
então eu resolvi fazer esse vídeo para trazer essa explicação para vocês.
Bons estudos, e até o próximo encontro.