
Prof. Paulo Rettore
Universidade Federal de Lavras
GAC124 — Introdução aos Algoritmos
Uma string representa uma sequência de caracteres. Ela é prática para nomes, frases e mensagens.
string nome = "Ana";
Também pode conter espaços.
Cada posição tem um índice.
Inclua <string> e use std::string ou using namespace std.
stringTipo da biblioteca C++ para textos. Conhece seu tamanho e oferece funções como find() e replace().
char[]Vetor de caracteres. Para representar uma C-string, precisa terminar com o caractere nulo \0.
char letras1[4] = {'i', 'a', 'l', 'g'}; // vetor de char
char letras2[5] = {'i', 'a', 'l', 'g', '\0'}; // C-string
Sem \0, o vetor não informa onde o texto termina. Para as atividades da disciplina, prefira string quando não houver motivo para usar char[].
length()Quantidade de caracteres da string.
size()Faz a mesma contagem em uma string.
strlen()Conta uma C-string até encontrar \0.
#include <cstring>
string nome = "IAlg";
char palavra[] = "UFLA";
cout << nome.length(); // 4
cout << nome.size(); // 4
cout << strlen(palavra); // 4
length() e size() são métodos de string; strlen() é uma função para vetores de caracteres terminados em \0.
string nome = "Ana";
string sobrenome = "Silva";
string completo = nome + " " + sobrenome;
cout << completo;
completo[0] = 'a'; // altera uma posição
completo.size()
completo[0]
texto1 + texto2
<string>Além de guardar texto, string oferece operações para localizar, remover e substituir partes da sequência.
#include <string>
std::string frase = "IAlg em C++";
size_t pos = frase.find("C++");
if (pos != std::string::npos)
cout << "Encontrado na posição " << pos;
frase.replace(0, 4, "Aula"); // substitui "IAlg" por "Aula"
frase.erase(4, 3); // remove " em"
Como interpretar: replace(posição, quantidade, novo texto). Como "IAlg" tem 4 caracteres, replace(0, 4, "Aula") produz "Aula em C++". Usar 0, 3 deixaria o g no texto.
find()Busca um trecho e retorna sua posição.
erase()Remove caracteres a partir de uma posição.
replace()Troca um trecho por outro.
Funções como find() retornam uma posição quando encontram o trecho. Quando não encontram, retornam o marcador especial std::string::npos.
std::string frase = "IAlg em C++";
size_t pos = frase.find("Python");
if (pos == std::string::npos)
cout << "Trecho não encontrado";
pos recebe um índice válido: 0, 1, 2...
pos recebe std::string::npos, uma constante que significa “posição inexistente”.
Use pos != std::string::npos para testar sucesso. Não dependa do número interno da constante e não compare diretamente com -1.
cin lê até o espaçostring nome;
cin >> nome;
Se a entrada for Paulo Rettore, o cin lê apenas Paulo.
O operador >> pula espaços no início e para no próximo espaço. Para ler uma linha inteira, use getline().
getline() lê a linha inteirastring frase;
getline(cin, frase);
cout << frase;
getline() lê até a quebra de linha e preserva os espaços internos.
Paulo Rettore
getline()
nome completo
\n no bufferint idade;
string nome;
cin >> idade;
getline(cin, nome); // pode ler vazio
Depois de cin >>, a quebra de linha pode permanecer no buffer. O getline() encontra essa quebra imediatamente.
cin.ignore()#include <limits>
int idade;
string nome;
cin >> idade;
cin.ignore(numeric_limits<streamsize>::max(), '\n');
getline(cin, nome);
Descartamos tudo até o fim da linha antes de ler o nome completo. Para uma entrada simples, cin.ignore() também pode ser suficiente.
O terceiro argumento de getline() define o delimitador. A leitura termina no separador, que é consumido e não entra no texto.
string nome, cidade;
// Entrada: Ana Silva;Lavras
getline(cin, nome, ';');
getline(cin, cidade); // até o fim da linha
cout << nome << " mora em " << cidade;
A mesma ideia funciona com cin, ifstream e stringstream. Use o delimitador que o arquivo realmente utiliza: ';', ',' ou outro.
Antes do código, observe o arquivo badassComputerPeople.csv usado nesta aula.
#nome,sexo,pais,ano de nascimento,ano de falecimento,descrição
10,,,,,
Ada Lovelace,F,Inglaterra,1815,1852,É considerada a primeira programadora de computador, a liguagem Ada foi nomeada em sua homenagem
Charles Babbage,M,Inglaterra,1791,1871,Projetou a máquina analítica, um modelo de computador
Alan Turing,M,Inglaterra,1912,1954,Um dos maiores teóricos da computação, criou a máquina de Turing, modelo teórico de um computador. Também é autor do Teste de Turing, para avaliar se uma IA pode se passar por um ser humano
John von Neuman,M,Hungria,1903,1957,Proponente da arquitetura de von Neuman, que é a base dos computadores modernos
Blaise Pascal,M,França,1623,1662,Inventor da calculadora mecânica, a linguagem Pascal foi nomeada em sua homenagem
Hedy Lamar,F,Áustria,1914,2000,Atriz, inventou, com o compositor George Antheil, um sistema de comunicações para as Forças Armadas dos Estados Unidos que serviu de base para a atual telefonia celular
George Antheil,M,EUA,1900,1959,Compositor, inventou, com a atriz Hedy Lamar, um sistema de comunicações para as Forças Armadas dos Estados Unidos que serviu de base para a atual telefonia celular
Noam Chomsky,M,EUA,1928,0,Fez diversas contribuições para a computação com seu trabalho em Linguística
Margaret Hamilton,F,EUA,1936,0,Criadora do termo 'Engenharia de Software', desenvolveu o conceito de software assíncrono
Bjarne Stroustrup,M,Dinamarca,1950,0,Criador do C++, odiado por vários alunos da UFLA
Nomeia os seis campos da tabela.
10 informa quantos registros serão lidos.
Depois vêm as dez pessoas, uma por linha.
O arquivo tem 12 linhas: cabeçalho, quantidade de registros e 10 registros de pessoas. A descrição é o último campo e pode conter vírgulas.
O programa lê diretamente do ifstream. Primeiro, descarta o cabeçalho e lê a quantidade de registros.
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main() {
string linha;
int numRegistros;
ifstream arquivo_csv("badassComputerPeople.csv");
if (not(arquivo_csv)) {
cout << "Erro: não foi possível abrir o arquivo!" << endl;
} else {
getline(arquivo_csv, linha); // cabeçalho
arquivo_csv >> numRegistros;
getline(arquivo_csv, linha); // resto da linha
// agora o fluxo está pronto para os registros
}
return 0;
}
Depois de >> numRegistros, o segundo getline() consome a quebra de linha que ficou pendente.
Dentro do laço, cada operador lê exatamente o próximo campo do registro.
for (int i = 0; i < numRegistros; i++) {
string nome, pais, descricao;
char sexo, lixo;
short anoNascimento, anoFalecimento;
getline(arquivo_csv, nome, ',');
arquivo_csv >> sexo;
arquivo_csv >> lixo; // descarta a vírgula
getline(arquivo_csv, pais, ',');
arquivo_csv >> anoNascimento >> lixo;
arquivo_csv >> anoFalecimento >> lixo;
if (arquivo_csv.peek() == '"') {
arquivo_csv.get(lixo); // abre-aspas
getline(arquivo_csv, descricao, '"');
getline(arquivo_csv, linha); // fim da linha
} else {
getline(arquivo_csv, descricao);
}
cout << "BCP #" << i + 1 << ":" << endl
<< nome << endl << sexo << endl
<< pais << endl
<< anoNascimento << "-" << anoFalecimento << endl
<< descricao << endl << endl;
}
peek() observa o próximo caractere sem removê-lo. Assim o código decide se a descrição começa entre aspas ou não.
getline(arquivo, nome, ',') lê até a próxima vírgula e preserva espaços.
arquivo >> anoNascimento converte a sequência para o tipo numérico.
arquivo >> lixo remove a vírgula que ficou no fluxo.
Ada Lovelace,F,Inglaterra,1815,1852,É considerada a primeira programadora, ...
nome = "Ada Lovelace"
sexo = 'F'
pais = "Inglaterra"
anoNasc. = 1815
anoFalec. = 1852
descricao = "É considerada a primeira programadora, ..."
A descrição é lida por último até o fim da linha. Por isso, as vírgulas dentro dela não deslocam os campos anteriores.
lixo descarta caracteres específicos; ela não valida se o separador realmente era uma vírgula.Escolha da técnica: use a leitura direta para arquivos simples e conhecidos. Depois veremos stringstream para separar uma linha já carregada e converter campos com mais flexibilidade.
<sstream> e stringstream?#include <sstream>Inclui as classes que tratam uma string como um fluxo de entrada e saída, usando a memória do programa.
stringstreamÉ um objeto que recebe uma linha já lida e permite extrair seus campos aos poucos, usando >> ou getline().
#include <sstream>
std::string linha = "Ada Lovelace,F,Inglaterra,1815,1852,Descrição";
std::stringstream campos(linha);
stringstream não abre arquivo e não lê diretamente do teclado: ele organiza uma string que já está na memória.
stringstream: separar uma linhaPodemos carregar uma linha inteira e depois extrair os campos. No arquivo desta aula, o último campo é lido sem delimitador para preservar suas vírgulas.
string linha = "Ada Lovelace,F,Inglaterra,1815,1852,Descrição";
stringstream campos(linha);
string nome, pais, descricao;
char sexo;
short anoNascimento, anoFalecimento;
getline(campos, nome, ',');
campos >> sexo >> lixo;
getline(campos, pais, ',');
campos >> anoNascimento >> lixo;
campos >> anoFalecimento >> lixo;
getline(campos, descricao); // restante da linha
Cada leitura avança o cursor de campos. O último getline() captura o restante, inclusive vírgulas da descrição.
stringstream#include <fstream>
#include <sstream>
ifstream arquivo("badassComputerPeople.csv");
string linha;
int numRegistros;
getline(arquivo, linha); // cabeçalho
arquivo >> numRegistros;
getline(arquivo, linha); // resto da linha
for (int i = 0; i < numRegistros; i++) {
getline(arquivo, linha);
stringstream campos(linha);
string nome, pais, descricao;
char sexo, lixo;
short nascimento, falecimento;
getline(campos, nome, ',');
campos >> sexo >> lixo;
getline(campos, pais, ',');
campos >> nascimento >> lixo;
campos >> falecimento >> lixo;
getline(campos, descricao);
}
Comparação: a leitura direta trabalha no arquivo enquanto avança; com stringstream, primeiro lemos a linha e depois processamos uma cópia dela em memória.
; ou ,.getline() para preservar espaços em nomes e descrições.Um CSV não é necessariamente separado por vírgulas: no Brasil, o ponto e vírgula é comum quando a vírgula aparece em números decimais.
string palavra = "algoritmo";
int vogais = 0;
for (int i = 0; i < palavra.size(); i++) {
char c = palavra[i];
if (c == 'a' or c == 'e' or c == 'i' or
c == 'o' or c == 'u')
vogais++;
}
Uma string pode ser percorrida como uma sequência de caracteres. O índice inicial é 0 e o último índice é size() - 1.
Leia a idade e o nome completo de uma pessoa. Depois, mostre uma mensagem de apresentação.
cin.cin.ignore() quando necessário.getline().Amplie o desafio: leia também cidade e curso em uma linha separada por ;.
Leia uma linha no formato nome;cidade;curso e mostre cada campo em uma linha diferente.
Entrada: Maria Silva;Lavras;Engenharia
Saída esperada:
Nome: Maria Silva
Cidade: Lavras
Curso: Engenharia
Gabarito orientador: use getline(cin, campo, ';') para os dois primeiros campos e um getline(cin, campo) para o último.
Use estas fontes para consultas pontuais depois da aula:
Os slides completos, o Campus Virtual e o DREDD continuam sendo as fontes principais da disciplina.
string armazena textos e possui length(), size(), find(), erase() e replace().std::string::npos indica que uma busca não encontrou o trecho procurado.cin lê uma palavra; getline() lê uma linha inteira ou um campo até um separador.cin >>, descarte a quebra de linha quando necessário.#include <sstream> disponibiliza o stringstream para separar e converter textos em memória.ifstream, getline() e stringstream.PRÓXIMA AULA
Prof. Paulo Rettore
GAC124 — Introdução aos Algoritmos