Cómo leer hasta EOF desde cin en C++

4 minutos de lectura

Estoy codificando un programa que lee datos directamente desde la entrada del usuario y me preguntaba cómo podría (sin bucles) leer todos los datos hasta EOF desde la entrada estándar. estaba considerando usar cin.get( input, '\0' ) pero '\0' no es realmente el caracter EOF, que solo lee hasta EOF o '\0'lo que sea que venga primero.

¿O usar bucles es la única forma de hacerlo? Si es así, ¿cuál es la mejor manera?

Como leer hasta EOF desde cin en C
trotterdylan

La única forma en que puede leer una cantidad variable de datos de stdin está usando bucles. Siempre he encontrado que el std::getline() la función funciona muy bien:

std::string line;
while (std::getline(std::cin, line))
{
    std::cout << line << std::endl;
}

Por defecto getline() lee hasta una nueva línea. Puede especificar un carácter de terminación alternativo, pero EOF no es un carácter en sí mismo, por lo que no puede simplemente hacer una llamada a getline().

  • Algo que debe tener cuidado aquí es cuando está leyendo archivos que se han canalizado a través de stdin, es que esta y la mayoría de las respuestas dadas agregarán un avance de línea adicional al final de su entrada. No todos los archivos terminan con un avance de línea, sin embargo, cada iteración del ciclo agrega “std::endl” a la secuencia. Esto puede no ser un problema en la mayoría de los casos, pero si la integridad del archivo es un problema, esto puede volver a molestarlo.

    – Zoccadoum

    29 de marzo de 2016 a las 0:41

  • Esta no debería ser la respuesta más votada. Vea la siguiente respuesta wiki de la comunidad. Además, tal vez vea esta pregunta: stackoverflow.com/questions/3203452/…

    – loxaxs

    16 de agosto de 2017 a las 10:21

Como leer hasta EOF desde cin en C
Degvik

Usando bucles:

#include <iostream>
using namespace std;
...
// numbers
int n;
while (cin >> n)
{
   ...
}
// lines
string line;
while (getline(cin, line))
{
   ...
}
// characters
char c;
while (cin.get(c))
{
   ...
}

recurso

Puede hacerlo sin bucles explícitos utilizando iteradores de flujo. Estoy seguro de que utiliza algún tipo de bucle internamente.

#include <string>
#include <iostream>
#include <istream>
#include <ostream>
#include <iterator>

int main()
{
// don't skip the whitespace while reading
  std::cin >> std::noskipws;

// use stream iterators to copy the stream to a string
  std::istream_iterator<char> it(std::cin);
  std::istream_iterator<char> end;
  std::string results(it, end);

  std::cout << results;
}

  • Agradable. En cuanto a “Estoy seguro de que usa algún tipo de bucle interno”, cualquier solución lo haría.

    – Michael Burr

    14 de octubre de 2008 a las 17:39

  • Esto parece eliminar los caracteres de nueva línea de la entrada, incluso si aparecen justo en el medio.

    – Multisincronización

    7 de septiembre de 2017 a las 8:44

Después de investigar la solución de KeithB usando std::istream_iteratordescubrí la std:istreambuf_iterator.

Pruebe el programa para leer toda la entrada canalizada en una cadena, luego escríbalo nuevamente:

#include <iostream>
#include <iterator>
#include <string>

int main()
{
  std::istreambuf_iterator<char> begin(std::cin), end;
  std::string s(begin, end);
  std::cout << s;
}

Probablemente más simple y generalmente eficiente:

#include <iostream>
int main()
{
    std::cout << std::cin.rdbuf();
}

Si es necesario, use secuencias de otros tipos como std::ostringstream como búfer en lugar de flujo de salida estándar aquí.

  • ustedes ya lo saben, pero puede ser útil para algunos: std::ostringstream std_input; std_input << std::cin.rdbuf(); std::string s = std_input.str() . usted tiene toda la entrada en s (ten cuidado con std::string si la entrada es demasiado grande)

    – ribamar

    1 de diciembre de 2015 a las 17:42


Nota al margen triste: decidí usar C ++ IO para ser consistente con el código basado en impulso. De las respuestas a esta pregunta elegí while (std::getline(std::cin, line)). Usando g ++ versión 4.5.3 (-O3) en cygwin (mintty) obtuve un rendimiento de 2 MB / s. Microsoft Visual C++ 2010 (/O2) hizo 40 MB/s para el mismo código.

Después de reescribir el IO a C puro while (fgets(buf, 100, stdin)) el rendimiento saltó a 90 MB/s en ambos compiladores probados. Eso marca la diferencia para cualquier entrada de más de 10 MB…

  • ustedes ya lo saben, pero puede ser útil para algunos: std::ostringstream std_input; std_input << std::cin.rdbuf(); std::string s = std_input.str() . usted tiene toda la entrada en s (ten cuidado con std::string si la entrada es demasiado grande)

    – ribamar

    1 de diciembre de 2015 a las 17:42


Puedes usar el estándar::istream::getline() (o preferiblemente el versión que funciona en std::string) función para obtener una línea completa. Ambos tienen versiones que le permiten especificar el delimitador (carácter de fin de línea). El valor predeterminado para la versión de cadena es ‘\n’.

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad