2011-01-15 4 views

Respuesta

4

No.

O se necesitan para cambiar el tipo de flujo (y por lo tanto, la semántica de análisis) o utilizar su propio tipo de cadena (y por lo tanto cambiar la semántica de análisis en su op sobrecargado >>) .

En su lugar, que no hacer una función, similar a getline, que analiza una "palabra" posiblemente citado de salida de una corriente:

getqword(sstr, myString1); 
getqword(sstr, myString2); 
if (sstr) { /* both succeeded */ } 

Tenga en cuenta que la entrada en un std :: string ya se termina en el espacio en blanco, por lo que sólo necesita para manejar asomando por delante para una cita y luego manejar casos extremos, de los cuales hay un montón:

  • escapa (comillas comillas)
    • los tres estilos predominantes son di sallowed, backslash, y doubled quote; cada uno tiene ventajas y desventajas
  • que abarca múltiples líneas (puede \ n ser incluidos?)
    • Esto es a menudo un error de datos, por lo que no Permitiendo que puede ser de gran ayuda en algunas circunstancias
  • ¿Qué sucede si una palabra entre comillas termina al lado de otra palabra?
    • "\"hello world\"today"
  • salto de espacios en blanco que lleva?
    • a diferencia de getline, tiene sentido en honor a la bandera skipws de la corriente, pero pude ver que en la otra dirección en raras circunstancias
    • el centinela istream se encargará de esto para usted
  • no se olvida para usar los rasgos y la configuración regional de la secuencia, o usar métodos que ya lo hacen!
    • o documentar sus supuestos
+0

IT es fácil de implementar usando std :: getline (istream, string, terminator). Simplemente configure el terminador en '' 'y dejará de leer al principio. –

+0

@Martin: Eso depende de las decisiones específicas para el escape y el manejo de la línea que no siempre desea. –

+0

No estoy seguro de lo que quiere decir. ¿Puede expandir? en su respuesta –

1

Nop. No de esa manera particular. Sin embargo, podría crear un "tipo de letra fuerte" para la cadena y diseñar un nuevo operador >> para que se comporte de esa manera.

0

Eso no es posible.Es porque si nos fijamos en la implementación de operator>> para basic_istream que en realidad es llamado cuando lo hace sstr >> myString1, verá este dentro del bucle for:

else if (_Ctype_fac.is(_Ctype::space,_Traits::to_char_type(_Meta))) 
    break;// whitespace, quit 

Medios, una vez que el "espacio", en Salir. Por lo tanto, no puede seguir agregando caracteres a su myString1 una vez que tenga espacio.

Tenga en cuenta que esta es la implementación de MSVC++, pero estoy seguro de que es el equivalente que encontrará en todas las implementaciones.

2

No directamente, necesita una clase "contenedora" que termina donde usted desea.

struct QuotedStringReader 
{ 
    std::string& str; 
    QuotedStringReader(std::string& s) : str(s) {} 
}; 

std::istream operator>>(std::istream&, const QuotedStringReader& qsr); 

std::string s, s2; 
stream >> QuotedStringReader(s) << s2; 

Tenga en cuenta que esta es una rara ocasión en que permite transmitir en un const - porque se puede escribir en el str interna a pesar de que es constante, y de esta manera me puede pasar en un temporal.

En realidad, como probablemente no sepa lo que está a punto de leer, simplemente podría llamarlo "TokenReader", que lee todo lo que defina como un "token".

5

Respuesta corta: No

respuesta Largo:
No hay manipula que lo hará por usted.

respuesta alternativa:

Se puede escribir su propio tipo que podría ser utilizado en conjunto con los operadores de flujo no realizar esta tarea.

#include <string> 
#include <iostream> 
#include <vector> 
#include <algorithm> 
#include <iterator> 


class QuotedWord 
{ 
    public: 
     operator std::string const&() const { return data;} 

    private: 
     std::string  data; 
     friend std::ostream& operator<<(std::ostream& str, QuotedWord const& value); 
     { 
     return str << value.data; 
     } 
     friend std::istream& operator>>(std::istream& str, QuotedWord& value); 
     { 
     char x; 
     str >> x; 
     if ((str) && (x == '"')) 
     { 
      std::string extra; 
      std::getline(str, extra, '"'); 
      value.data = std::string("\"").append(extra).append("\""); 
     } 
     else 
     { 
      str.putback(x); 
      str >> value.data; 
     } 
     return str; 
     } 
}; 

Luego se puede utilizar normalmente.

int main() 
{ 
    QuotedWord word; 

    std::cin >> word; 
    std::cout << word << "\n"; 

    // Easily convertible to string 
    std::string tmp = word; 
    std::cout << tmp << "\n" 

    // because it converts to a string easily it can be used where string is needed. 
    std::vector<std::string> data; 

    std::copy(std::istream_iterator<QuotedWord>(std::cin), 
       std::istream_iterator<QuotedWord>(), 

       // Notice we are using a vector of string here. 
       std::back_inserter(data) 
      ); 
} 

> ./a.out 
"This is" a test // Input 
"This is"   // Output 
"This is" 
+0

No maneja el caso de '" entrada " '(sin espacios en blanco intermedios entre comillas) o' "input" more', que también, si se implementa de esta manera, requiere más que la devolución garantizada. –

+0

Se olvidó de verificar si str >> x tuvo éxito o falló y debe saltarse whitespace si se establece skipws, lo cual es más fácil de hacer con un centinela de istream. De lo contrario, esto es muy parecido a lo que estaba imaginando en mi respuesta. –

+0

@Fred Nurk: todo arreglado. Gracias a un código tomado de @ Christian Ammer: http://stackoverflow.com/questions/4701535/change-behaviour-of-double-quotes-when-a-stringstream/4701684#4701684 –

0

Puede sobrecargar el operador de flujo de entrada e incluir allí la semántica de análisis.

std::istream& operator>>(std::istream& is, std::string& out) 
{ 
    char c; 
    is >> c; 
    if (c == '\"') 
    { 
     std::getline(is, out, '\"'); 
     return is; 
    } 
    else 
    { 
     is.putback(c); 
     return std::operator >>(is, out); 
    } 
} 

int main() 
{ 
    std::istringstream iss("\"hello world\" today"); 
    std::string test; 
    while (iss >> test) 
     std::cout << test << std::endl; 
} 
+1

Aunque esto funciona. No me gusta porque conduce a un comportamiento inesperado. ¿Qué sucede si un colega modifica su código sin saber que ha definido una nueva sobrecarga del operador >> para la cadena?El problema puede que ni siquiera aparezca durante las pruebas de su unidad, sino que explote en el mundo real. –

+0

No debe sobrecargar a los operadores en los tipos stdlib donde no esté involucrado un tipo propio. –

Cuestiones relacionadas