Changing the behavior of double quotes when >> stringstream

Here is what I am trying to do:

Say I have a string stream. Then I<< "\"hello world\" today";

then when i do

sstr >> myString1 >> myString2;

I want myString1 to have “hello world”, and for myString2 to have “today”

Is there a way, possibly with a manipulator, to achieve this?

thank

+5
source share
6 answers

No.

You need to either change the type of the stream (and therefore the semantics of the parsing), or use your own string type (and, therefore, change the semantics of the parsing in the overloaded operator →).

, getline, "" :

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

, std::string , peeking , , :

  • escape ( )
    • , ; .
  • ( \n ?)
    • , .
  • , ?
    • "\"hello world\"today"
  • ?
    • getline, , , .
    • istream sentry
  • , , !
+4

:

:
, .

:

, , .

#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;
      }
};

.

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"
+5

, "wrapper", , .

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;

, , const, , , .

, , , , , "TokenReader", , "".

+2

. . " typedef" → , .

+1

. , operator>> basic_istream, , sstr >> myString1, for:

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

So, as soon as you get a "space", exit. Thus, you will not be able to add characters to yours myString1after you get space.

Please note that this is an implementation of MSVC ++, but I am sure that the equivalent that you will find in the whole implementation!

0
source

You can overload the input stream operator and include semantics parsing into it.

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;
}
0
source

All Articles