2011-02-02 6 views
21

Cada vez que hago un fragmento rápida de C++ línea de código¿Por qué hay dos funciones getline() diferentes (si es que las hay)?

std::string s; 
cin >> s; 

Me maldigo porque se me olvidó que se detenga en el espacio en blanco en lugar de obtener una línea completa.

Luego, en recordar getline, invariablemente se confunden en cuanto a las dos variedades:

std::string s; 
getline (std::cin, s); 

y:

char cs[256]; 
std::cin.getline (cs, sizeof (cs)); 

¿Existe realmente una diferencia entre estos dos que no sea el tipo de datos?

Me parece que la forma C++ debe ser la primera. ¿Bajo qué circunstancias usaría este último, dado que probablemente debería estar usando cadenas reales en su lugar de matrices de caracteres terminados en nulo?

Y, dado que la entrada debería ser realmente el ámbito de las secuencias de entrada, ¿por qué no es la parte anterior de istream?

Respuesta

8

Tenga en cuenta que la biblioteca estándar se compone de 3 partes (principales): IOStream, String y STL, más algunos lanzados en golosinas y los C-encabezados.

No veo nada raro en tener esas partes ligeramente acopladas (aunque desearía que no fuera el caso).

Otras incongruencias incluyen: std::string::length vs std::string::size, esta última se ha agregado para compatibilidad de interfaz con el STL y la anterior se ha conservado para compatibilidad con código anterior.

+3

Creo que la frase está "vagamente acoplada", "mal integrada" tiene connotaciones negativas. Creo que es una buena cosa (tm) que puedas usar 'std :: string' sin necesidad de' std :: istream' y usar 'std :: istream' sin necesidad de' std :: string'. –

+2

@Charles: ¿me creerías si te dijera que hice el cambio exactamente opuesto antes de presionar "enviar" :)? Yo personalmente hubiera preferido una biblioteca estándar más "uniforme". La biblioteca estándar de C++ es el epítome del "crecimiento orgánico". –

+2

@Charles: Definitivamente creo que está mal que iostreams y string no estén acoplados. Quiero decir, iostream depende de la manipulación de cadenas, en un nivel básico. Reducir las dependencias es una cosa, proporcionar funciones miembro que funcionen con C-string es inexcusable si no eres la clase de cadena. – Puppy

1

La variante getline dentro de la biblioteca iostreams no admite cadenas como destinos, por lo que la biblioteca de cadenas definió una variante que sí lo hace.

22

La función global getline() funciona con objetos C++ std::string.

Los métodos istream::getline() funcionan con cadenas de caracteres "clásicas" (punteros a char).

+0

Entonces, si lo único que introduce son cadenas, ¿por qué no 's.getline (std :: cin)' en lugar de romper mi encantadora 'object.method()' vista del mundo? – paxdiablo

+3

@paxdiablo, podría ser una cuestión de semántica: 'getline()' es una operación de secuencia, no una operación de cadena, por lo que sería extraño hacerlo un método de la clase 'std :: string'. –

+4

Supongo que no sabe acerca de , por lo tanto std :: cin no puede tener el método que devuelve std :: string. – Grozz

1

Sí, la forma moderna de C++ es usar la función gratuita e ingresar una std :: cadena.

Pero IOStream tiene un historial mucho más largo (la versión estándar es al menos la tercera encarnación del mismo diseño) que std :: string y esa historia explica por qué las cosas son como son.

(El miembro getline tiene la ventaja de que no implica una asignación dinámica, esa característica puede ser útil en el tiempo pero probablemente no sea suficiente para justificarla en un diseño desde cero).

6

Es un problema de diseño de interfaz común. cin.getline() es una forma natural de realizar la solicitud, pero para evitar que el código de secuencia dependa de <string>, no se puede ofrecer la función cin.getline(std::string&). El getline(cin, s) autónomo puede agregarse más adelante una vez que las cadenas se hayan puesto dentro del alcance. No es un problema para char* ya que no hay nada para #include - todo forma parte del lenguaje de todos modos.

En cierto modo, es agradable cuando los idiomas permiten que el código posterior agregue más funciones a las clases existentes (por ejemplo, Ruby), pero en otras formas la delocalización muerde y, bueno, compromete la capacidad de mantenimiento. Luego, por supuesto, existe un argumento popular para las funciones mínimas de los miembros y muchas funciones autónomas: personalmente creo que no se debe tomar hasta el punto de hacer que la interfaz sea menos intuitiva y expresiva, pero cada una por su cuenta.

+0

Esta parece ser la única respuesta que establece explícitamente por qué este desacoplamiento es por diseño. El mero hecho de que 'string' sea más nuevo que' iostream' es, después de todo, en sí mismo una explicación suficiente de por qué este último no fue adaptado. Supongo que hubo un momento en el que la decisión fue menos controvertida, y la sobrecarga de tener una clase de 'cadena 'no utilizada fue relativamente mayor. –

Cuestiones relacionadas