Lendo uma linha inteira
cin >> text lê uma única palavra: para no primeiro espaço. Para ler tudo o que o usuário digitou até o Enter, espaços incluídos, use std::getline, do header <string>:
#include <iostream>
#include <string>
int main() {
std::string name;
std::cout << "Full name: ";
std::getline(std::cin, name);
std::cout << "Hello, " << name << "!\n";
}
Digitar Ada Lovelace imprime Hello, Ada Lovelace!. Com std::cin >> name ele imprimiria Hello, Ada! e deixaria Lovelace esperando na entrada.
A assinatura é:
std::istream& std::getline(std::istream& input, std::string& text);
std::istream& std::getline(std::istream& input, std::string& text, char delim);
inputé qualquer stream de entrada:std::cin, um arquivo aberto comstd::ifstreamou umstd::istringstreammontado a partir de uma string.texté substituído (não recebe texto no final) pelos caracteres lidos.delimé o caractere que encerra a leitura. O padrão é'\n'. O delimitador é removido do stream e não é guardado emtext.- O valor de retorno é o próprio stream, e é isso que permite testá-lo numa condição.
Como o getline funciona igual em qualquer stream de entrada, os exemplos executáveis desta página leem de um std::istringstream com texto fixo. Assim a saída é previsível sem você digitar nada. Para ler do teclado, troque a variável do stream por std::cin.
Saída:
[Ada Lovelace]
[Alan Turing]
Os colchetes mostram que a quebra de linha não faz parte de nenhuma das strings.
getline depois de cin >> retorna uma string vazia
Este é o problema mais comum com o getline. Você lê um número com >>, depois uma linha com getline, e o getline parece ser pulado:
Saída:
age: 30
city: []
input >> age lê os caracteres 30 e para no primeiro caractere que não pode fazer parte de um número, a quebra de linha. Essa quebra de linha fica no stream. O getline então lê até a próxima quebra de linha, encontra uma imediatamente e retorna uma string vazia. Com std::cin, o efeito é que o programa nunca espera pela segunda resposta.
Há duas correções padrão. As duas vão entre o >> e o getline.
Correção 1: descartar o resto da linha com ignore.
Saída:
age: 30
city: [Paris]
ignore(n, '\n') joga fora caracteres até ter removido uma quebra de linha ou n caracteres, o que vier primeiro. Passar o maior std::streamsize possível significa "até a quebra de linha, esteja ela onde estiver". Isso também remove qualquer coisa que o usuário tenha digitado depois do número na mesma linha, como espaços no final. Com o teclado, a linha é std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');, e ela precisa de #include <limits>.
Um std::cin.ignore() sem argumentos descarta exatamente um caractere. Funciona quando a quebra de linha vem logo depois do número, e falha assim que há um espaço antes dela.
Correção 2: pular os espaços em branco iniciais com std::ws.
Saída:
age: 30
city: [Paris]
std::ws é um manipulador que consome todo o espaço em branco (espaços, tabs, quebras de linha) na posição atual. input >> std::ws retorna o stream, então pode ir direto para o getline. Ele também pula linhas em branco e espaços no início, o que é prático para nomes e cidades, mas errado quando espaços iniciais ou uma linha vazia são entradas com significado. Nesse caso, use ignore.
Lendo até o fim da entrada
getline retorna o stream, e um stream se converte em false quando uma leitura falha. Quando não há mais linhas, o getline falha, então um laço while em volta dele lê todas as linhas e para no fim:
Saída:
1: [apples 3]
2: [bread 1]
3: []
4: [milk 2]
read 4 lines
Dois detalhes dessa saída:
- Uma linha vazia continua sendo uma leitura bem-sucedida. Ela dá uma string vazia e o laço continua. Só chegar ao fim da entrada o interrompe.
- A última linha não precisa de uma quebra de linha no final. Se o texto terminasse em
milk 2sem\n, ogetlineainda a retornaria, e a chamada seguinte falharia.
Com std::cin, o mesmo laço lê até a entrada acabar. Isso acontece quando a entrada vem de um arquivo por redirecionamento (./program < data.txt), ou quando o usuário aperta Ctrl+D no macOS e no Linux, ou Ctrl+Z e depois Enter no Windows.
Evite o padrão while (!input.eof()) { std::getline(input, line); ... }. eof() só fica verdadeiro depois que uma leitura já bateu no fim, então o corpo roda uma vez a mais com uma leitura que falhou e um line desatualizado. Coloque a chamada de getline na condição.
Lendo um arquivo linha por linha
Arquivos usam o mesmo laço. Abra o arquivo com std::ifstream, de <fstream>, confira se ele abriu e leia:
Saída:
1. Ada 92
2. Grace 88
3. Alan 95
if (!file) pega um arquivo inexistente ou um caminho errado antes do laço. Sem isso, o laço simplesmente lê zero linhas, o que parece um arquivo vazio e não um erro. O arquivo fecha automaticamente quando file sai de escopo no fim do main.
Arquivos salvos no Windows terminam cada linha com \r\n. Quando um arquivo assim é lido no Linux ou no macOS, o getline remove o \n mas mantém o \r, e toda linha termina com um retorno de carro invisível que quebra comparações como line == "done". Remova-o depois de ler:
if (!line.empty() && line.back() == '\r') {
line.pop_back();
}
Usando um delimitador personalizado
O terceiro argumento muda o caractere que encerra cada leitura. Um uso comum é dividir uma linha nas vírgulas. Leia a linha primeiro e depois divida-a com um std::istringstream:
Saída:
fields: 3
[Ada Lovelace]
[36]
[London]
A vírgula é removida do stream e não é guardada, do mesmo jeito que a quebra de linha na forma padrão. Repare que, com um delimitador personalizado, a quebra de linha é um caractere comum. Se você chamar std::getline(file, field, ',') direto num arquivo de várias linhas, o último campo de uma linha e o primeiro campo da seguinte voltam grudados, como em "London\nGrace Hopper". Ler uma linha por vez e dividir cada linha separadamente evita isso. A página de string streams aprofunda o std::istringstream, incluindo a conversão de campos como "36" em números.
std::getline vs cin.getline
Também existe uma função membro com nome parecido:
char buffer[20];
std::cin.getline(buffer, 20); // função membro, array de char de tamanho fixo
std::string text;
std::getline(std::cin, text); // função livre, std::string
cin.getline escreve num array de char e guarda no máximo size - 1 caracteres mais o '\0' final. Uma linha mais longa coloca o stream em estado de falha, e toda leitura posterior é pulada até você chamar std::cin.clear(). std::getline com uma std::string não tem limite de tamanho para você controlar. Use-o, a menos que esteja trabalhando com uma API que exige um array de char.
Erros comuns
- Misturar
>>egetlinesem limpar a quebra de linha. Adicioneignore(...)ou usestd::wsentre os dois. A página de entrada e saída mostra o mesmo problema comstd::cine como se recuperar quando uma leitura numérica falha. - Chamar
getline(std::cin, number)com umint.getlinesó lê para umastd::string. Leia a linha e depois converta comstd::stoiou umstd::istringstream. - Fazer o laço com
eof(). Teste a própria chamada degetline:while (std::getline(input, line)). - Esquecer
#include <string>. Ostd::getlinepara strings é declarado em<string>. Alguns compiladores deixam passar via<iostream>, e o código falha em outro compilador. - Não verificar se o arquivo abriu. Um caminho errado faz o
std::ifstreamfalhar em silêncio e o laço de leitura rodar zero vezes.
Perguntas frequentes
O que o getline faz em C++?
std::getline(stream, text) lê caracteres de stream para a std::string text até encontrar uma quebra de linha, e então remove essa quebra de linha do stream sem guardá-la. Ao contrário de cin >> text, ele mantém os espaços, então lê uma linha inteira, como um nome completo ou uma frase.
Por que o getline é pulado depois de cin >> em C++?
cin >> number para de ler na quebra de linha que você digitou depois do número e deixa essa quebra de linha no buffer de entrada. O getline seguinte a encontra imediatamente e retorna uma string vazia. Descarte-a antes com std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');, ou chame std::getline(std::cin >> std::ws, text) para pular os espaços em branco iniciais.
Como usar getline com um delimitador diferente da quebra de linha?
Passe o delimitador como terceiro argumento: std::getline(stream, field, ','). Ele lê até a próxima vírgula, guarda o texto antes dela e descarta a vírgula. As quebras de linha passam a ser caracteres comuns, então isso costuma ser combinado com um std::stringstream montado a partir de uma única linha.
Como ler um arquivo linha por linha em C++?
Abra com std::ifstream file("data.txt"); e faça um laço com while (std::getline(file, line)) { ... }. getline retorna o stream, que se converte em false quando não há mais linhas, então o laço para no fim do arquivo.
Qual a diferença entre cin.getline e getline?
std::getline(std::cin, text) é uma função livre que lê para uma std::string, que cresce para caber qualquer linha. std::cin.getline(buffer, size) é uma função membro que lê para um array fixo de char e falha se a linha tiver mais de size - 1 caracteres. Use std::getline com std::string, a menos que você tenha um motivo para usar arrays crus.