Pergunta

Eu estou escrevendo um pequeno programa para meu uso pessoal para a prática de aprender C ++ e pela sua funcionalidade, um gerador de citação MLA (Eu estou escrevendo um grande papel com dezenas de citações).

Por falta de uma melhor maneira de fazê-lo (eu não entendo classes ou usando outros arquivos .cpp dentro do seu principal, por isso não me incomoda dizendo, eu vou trabalhar nisso quando tenho mais tempo), Eu estou escrevendo uma função para cada tipo de citação. I pode decompô-lo em uma função para cada código reutilizados se eu ficar mais tempo.

A minha pergunta é: como é que o std :: cin trabalho objeto? Atualmente, estou lendo com std :: cin >> para as cordas espero ser palavras isoladas, e getline (std :: cin, string) para as cordas com espaços. Eu não estou recebendo a saída certa, porém. Eu só quero saber como std :: cin obras e por isso que eu continuo inesperadamente pulando algumas alguns insumos (por exemplo, ele pula página web em vez de dar-me uma oportunidade de entrada para ele).

void webCit()
{
std::cout << "Leave any unknowns blank.\n";

std::cout << "Author last name: ";
std::string lastName;
std::cin >> lastName;

if (lastName.size() != 0)
{
    lastName = lastName + ", ";    
}


std::cout << "Author first name: ";
std::string firstName;
std::cin >> firstName;

if (firstName.size() != 0)
{
    firstName = firstName + ". ";
}


std::cout << "Article title: ";
std::string articleTitle;
getline(std::cin, articleTitle);

if (articleTitle.size() != 0)
{
    articleTitle = "\"" + articleTitle + ".\" ";
}

std::cout << "Title of web page: ";
std::string pageTitle;
std::cin >> pageTitle;

if(pageTitle.size() != 0)
{
    pageTitle = pageTitle + ". ";
}

std::cout << "Publication date: ";
std::string publicationDate;
getline(std::cin, publicationDate);

if(publicationDate.size() != 0)
{
    publicationDate = publicationDate + ". ";

} 

std::cout << "Web address: ";
std::string webAddress;
getline(std::cin, webAddress);

webAddress = "<" + webAddress + ">. ";

std::cout << "Date accessed: ";
std::string dateAccessed;
getline(std::cin, dateAccessed);

if(dateAccessed.size() != 0)
{
    dateAccessed = dateAccessed + ". ";
}

std::string citation =
    lastName + firstName + articleTitle + pageTitle + publicationDate + webAddress + dateAccessed;

std::cout << citation; //TEST; remove after
}

EDIT: I / O

Leave any unknowns blank.
Author last name: Hooked
Author first name: Jerbear
Article title: Title of web page: title
Publication date: Web address: www.win.com
Date accessed: 4/29/09
Hooked, Jerbear. Title. <www.win.com>. 4/29/09. 

Como você pode ver, algo está errado, porque a minha entrada está sendo pulado.

Foi útil?

Solução

O que está acontecendo aqui é que std::cin >> firstName; só lê até , mas não incluindo o primeiro caractere em branco, que inclui a nova linha (ou '\n') quando você pressionar Enter, então quando chega a getline(std::cin, articleTitle);, '\n' ainda é o próximo personagem em std::cin e getline() retorna imediatamente.

// cin = "Bloggs\nJoe\nMan of Steel, Woman of Kleenex\n"
std::cin >> lastName;
std::cin >> firstName;
// firstName = "Joe", lastName = "Bloggs", cin = "\nMan of Steel, Woman of Kleenex\n"
getline(std::cin, articleTitle);
// articleTitle = "", cin = "Man of Steel, Woman of Kleenex\n"

Adicionando 'std::cin >> std::ws' (ws significando whitespace) antes de suas chamadas para getline () corrige o problema:

std::cin >> firstName >> std::ws;
getline(std::cin, articleTitle);

Mas é mais fácil ver onde você perdeu-lo se você fizer isso no argumento:

std::cin >> firstName;
getline(std::cin >> std::ws, articleTitle);

Outras dicas

Quando você usa o operador >>, cin lê-se até o próximo caractere de espaço em branco, mas não processa o espaço em branco. Então, quando você tem

std::cin >> str1;
std::getline(std::cin, str2);

a segunda chamada será apenas processar o caractere de nova linha, e você não vai ter a chance de digitar em qualquer entrada.

Em vez disso, se você estiver planejando usar getline após uma operator >>, você pode chamar std::cin.ignore() comer a nova linha antes de chamar getline.

Edit: ele funciona como você esperava quando você faz

std::cin >> str1;
std::cin >> str2;

desde a segunda chamada irá ignorar todos os espaços em branco.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top