Pregunta

Estoy escribiendo un pequeño programa para mi uso personal para practicar el aprendizaje de C ++ y para su funcionalidad, un generador de citas MLA (estoy escribiendo un artículo grande con decenas de citas).

Por falta de una mejor manera de hacerlo (no entiendo clases o no uso otros archivos .cpp dentro de tu main, así que no te molestes en decirme, trabajaré en eso cuando tenga más tiempo), Estoy escribiendo una función para cada tipo de cita. Podría dividir esto en una función para cada código reutilizado si tengo más tiempo.

Mi pregunta es: ¿cómo funciona el objeto std :: cin? Actualmente estoy leyendo con std :: cin > > para las cadenas espero ser palabras simples, y getline (std :: cin, string) para las cadenas con espacios. Sin embargo, no estoy obteniendo la salida correcta. Solo quiero saber cómo funciona std :: cin y por qué sigo saltando inesperadamente algunas entradas (por ejemplo, salta en la página web en lugar de darme la oportunidad de ingresar).

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
}

EDITAR: E / S

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 puede ver, algo va mal, porque mi información se omite.

¿Fue útil?

Solución

Lo que está sucediendo aquí es que std :: cin > > firstName; solo lee hasta pero no incluye el primer carácter de espacio en blanco, que incluye la nueva línea (o '\ n' ) cuando presiona Intro, por lo que cuando llega a getline (std :: cin, articleTitle); , '\ n' sigue siendo el siguiente carácter en std :: cin , y getline () devuelve inmediatamente.

// 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"

Agregando ' std :: cin > > std :: ws '( ws significa w hite s pace) antes de que sus llamadas a getline () solucionen el problema:

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

Pero es más fácil ver dónde te lo perdiste si lo haces en el argumento:

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

Otros consejos

Cuando utiliza el operador > > , cin lee hasta el siguiente carácter de espacio en blanco, pero no procesa el espacio en blanco. Así que cuando tengas

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

la segunda llamada solo procesará el carácter de nueva línea, y no tendrás la oportunidad de escribir ninguna entrada.

En cambio, si planea utilizar getline después de un operador > > , puede llamar a std :: cin.ignore () para comer la nueva línea antes de llamar a getline .

Editar: funciona como esperabas cuando lo haces

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

ya que la segunda llamada ignorará todos los espacios en blanco iniciales.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top