Using std::ws

M

mathieu

Hi,

I am having a hard time understanding how to use std::ws. I am
trying to parse a simple string (*). My goal would be that 'st'
contains 'Hello World'. I thought that using std::ws would indeed do
what I was looking for.

Thanks for suggestion,
-Mathieu

(*)
#include <iostream>
#include <sstream>

int main(int, char *[])
{
const char s[] = "1 2 3 Hello World";
std::istringstream is(s);
int a,b,c;
std::string st;
is >> a;
is >> b;
is >> c;
is >> std::ws;
is >> st;
std::cout << a << " " << b << " " << c << " " << st << std::endl;

return 0;
}
 
V

Victor Bazarov

mathieu said:
Hi,

I am having a hard time understanding how to use std::ws. I am
trying to parse a simple string (*). My goal would be that 'st'
contains 'Hello World'. I thought that using std::ws would indeed do
what I was looking for.

Thanks for suggestion,
-Mathieu

(*)
#include <iostream>
#include <sstream>

int main(int, char *[])
{
const char s[] = "1 2 3 Hello World";
std::istringstream is(s);
int a,b,c;
std::string st;
is >> a;
is >> b;
is >> c;
is >> std::ws;
is >> st;
std::cout << a << " " << b << " " << c << " " << st << std::endl;

return 0;
}

'std::ws' does not set some kind of "from now on consider whitespace
not whitespace any longer" flag. No such flag exists. 'std::ws' just
skips all whitespace from current position to the next non-whitespace
character.

What you need is "get the rest of the stream into my 'string'" action.
Instead of 'is >> st', use 'getline':

is >> std::ws;
std::getline(is, st); // not the shift.

V
 
M

mathieu

mathieu said:
I am having a hard time understanding how to use std::ws. I am
trying to parse a simple string (*). My goal would be that 'st'
contains 'Hello World'. I thought that using std::ws would indeed do
what I was looking for.
Thanks for suggestion,
-Mathieu
(*)
#include <iostream>
#include <sstream>
int main(int, char *[])
{
const char s[] = "1 2 3 Hello World";
std::istringstream is(s);
int a,b,c;
std::string st;
is >> a;
is >> b;
is >> c;
is >> std::ws;
is >> st;
std::cout << a << " " << b << " " << c << " " << st << std::endl;
return 0;
}

'std::ws' does not set some kind of "from now on consider whitespace
not whitespace any longer" flag. No such flag exists. 'std::ws' just
skips all whitespace from current position to the next non-whitespace
character.

What you need is "get the rest of the stream into my 'string'" action.
Instead of 'is >> st', use 'getline':

is >> std::ws;
std::getline(is, st); // not the shift.

Thanks ! Worked perfectly. I misunderstood the documentation.

-Mathieu
 
R

Robert Bauck Hamar

mathieu said:
Hi,

I am having a hard time understanding how to use std::ws. I am
trying to parse a simple string (*). My goal would be that 'st'
contains 'Hello World'. I thought that using std::ws would indeed do
what I was looking for.

istream >> string

Reads until it finds whitespace. Unfortunately, the space between the words
is whitespace. You could alter this behaviour by changing the locale, but
the easiest solution is to use the getline function.
#include <iostream>
#include <sstream>

#include <string>
#include <istream>

Formally, you need these two headers. Though most implementations of
int main(int, char *[])
{
const char s[] = "1 2 3 Hello World";
std::istringstream is(s);
int a,b,c;
std::string st;
is >> a;
is >> b;
is >> c;
is >> std::ws;
is >> st;

Change this last line to
std::getline(is, st);
 
?

=?ISO-8859-1?Q?Erik_Wikstr=F6m?=

Hi,

I am having a hard time understanding how to use std::ws. I am
trying to parse a simple string (*). My goal would be that 'st'
contains 'Hello World'. I thought that using std::ws would indeed do
what I was looking for.

Thanks for suggestion,
-Mathieu

(*)
#include <iostream>
#include <sstream>

int main(int, char *[])
{
const char s[] = "1 2 3 Hello World";
std::istringstream is(s);
int a,b,c;
std::string st;
is >> a;
is >> b;
is >> c;
is >> std::ws;
is >> st;
std::cout << a << " " << b << " " << c << " " << st << std::endl;

return 0;
}

No, std::ws will only extract the whitespace between the '3' and the
'Hello', but since you have not done 'is >> std::noskipws' it will be
skipped anyway (so 'is >> std::ws' will have no effect). I'm not sure
how to solve your problem but it might be possible to change the
delimiting characters somehow. Or if you know that the string will be at
the end use is.str().
 
B

BobR

Erik Wikström said:
Hi,
#include <iostream>
#include <sstream>

int main(int, char *[]){

// or just: 'int main(){}'
const char s[] = "1 2 3 Hello World";
std::istringstream is(s);
int a,b,c;
std::string st;
is >> a;
is >> b;
is >> c;
is >> std::ws;
is >> st;
std::cout << a << " " << b << " " << c << " " << st << std::endl;
return 0;
}

No, std::ws will only extract the whitespace between the '3' and the
'Hello', but since you have not done 'is >> std::noskipws' it will be
skipped anyway (so 'is >> std::ws' will have no effect). I'm not sure
how to solve your problem but it might be possible to change the
delimiting characters somehow.
Or if you know that the string will be at the end use is.str().

Oh?

// ....
is >> a >> b >> c;
is >> std::ws; // could be done with 'is.ignore( 1 );'
// is >> st;
st = is.str();
std::cout << a << " " << b << " " << c << " " << st << std::endl;
// out:1 2 3 1 2 3 Hello World

std::getline( is, st );
std::cout << a << " " << b << " " << c << " " << st << std::endl;
// out:1 2 3 Hello World
// ....

OP: If you only wanted to extract 'Hello' using std::getline(), you can set
the delimiter ('\n' is default).

// is >> st;
std::getline( is, st, ' ' ); // note: that's a single char, not " "
(string).

// (should) out:1 2 3 Hello
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,291
Messages
2,571,453
Members
48,137
Latest member
IndiraMcCo

Latest Threads

Top