string find

K

Ko van der Sloot

Hello
I was wondering which behaviour might be expected (or is required) for
the following small program.
I would expect that find( "a", string::npos ) would return string::npos
but is seems to be dependant on which string is searched for.

On my system, using gcc 4.1.2, I get:

pos1=2
problem because pos1=0
I expected this


#include <iostream>
#include <string>

using namespace std;

int main(){
string use = "anu";
string::size_type pos1 = use.find_first_not_of( "an" );
cerr << "pos1=" << pos1 << endl;
pos1 = use.find( "a", string::npos );
if ( pos1 == string::npos )
cerr << "I expected this" << endl;
else
cerr << "problem because pos1=" << pos1 << endl;
pos1 = use.find( "q", string::npos );
if ( pos1 == string::npos )
cerr << "I expected this" << endl;
else
cerr << "problem because pos1=" << pos1 << endl;
}
 
M

Mike Wahler

Ko van der Sloot said:
Hello
I was wondering which behaviour might be expected (or is required) for
the following small program.
I would expect that find( "a", string::npos ) would return string::npos
but is seems to be dependant on which string is searched for.

On my system, using gcc 4.1.2, I get:

pos1=2
problem because pos1=0
I expected this


#include <iostream>
#include <string>

using namespace std;

int main(){
string use = "anu";
string::size_type pos1 = use.find_first_not_of( "an" );
cerr << "pos1=" << pos1 << endl;
pos1 = use.find( "a", string::npos );
if ( pos1 == string::npos )
cerr << "I expected this" << endl;
else
cerr << "problem because pos1=" << pos1 << endl;
pos1 = use.find( "q", string::npos );
if ( pos1 == string::npos )
cerr << "I expected this" << endl;
else
cerr << "problem because pos1=" << pos1 << endl;
}

Why are you giving 'npos' as the second argument to 'find()'?
Do you know the meaning of the second argument?
Do you know what 'npos' is for?

-Mike
 
G

Gavin Deane

Why are you giving 'npos' as the second argument to 'find()'?
Do you know the meaning of the second argument?
Do you know what 'npos' is for?

Might be an odd thing to want to do in practice, but I'd be interested
in a definitive answer. My first thought was that maybe using npos as
the second argument to find has undefined behaviour, but I can't find
anything to back that up (doesn't mean it's not there of course). When
I compiled and ran the code using Visual Studio 2005, I got the output
I believe the OP ws expecting:

pos1=2
I expected this
I expected this

So I wonder whether the behaviour is undefined and I've just missed
where it says that, or has the OP found a compiler bug?

Gavin Deane
 
A

Andre Kostur

Might be an odd thing to want to do in practice, but I'd be interested
in a definitive answer. My first thought was that maybe using npos as
the second argument to find has undefined behaviour, but I can't find
anything to back that up (doesn't mean it's not there of course). When
I compiled and ran the code using Visual Studio 2005, I got the output
I believe the OP ws expecting:

pos1=2
I expected this
I expected this

So I wonder whether the behaviour is undefined and I've just missed
where it says that, or has the OP found a compiler bug?

AFAIK, the second argument to find is an index into the string.
string::npos is not a valid index into a string, so I would expect the
same impact as specifying an out-of-bounds index to find.
 
G

Gavin Deane

AFAIK, the second argument to find is an index into the string.
string::npos is not a valid index into a string, so I would expect the
same impact as specifying an out-of-bounds index to find.- Hide quoted text

21.3.6.1 (in the 1998 standard) doesn't mention any precondition that
the second argument to std::string::find must be a valid index.
Conditions that indicate the substring has been found are defined, and
it just says that if those conditons can not be met, the return is
npos. Based on that, I would conclude that the OP's compiler is wrong.

Gavin Deane
 
M

Mike Wahler

Gavin Deane said:
21.3.6.1 (in the 1998 standard) doesn't mention any precondition that
the second argument to std::string::find must be a valid index.

I believe it's implied in that the argument type is 'size_type'.
(My implementation's documentation describes 'size_type' as
"An unsigned integer type that can represent the number of elements
and indices in a string.")
Conditions that indicate the substring has been found are defined, and
it just says that if those conditons can not be met, the return is
npos.

Right. That's what npos is used for.
Based on that, I would conclude that the OP's compiler is wrong.

Undefined behavior is neither 'right' nor 'wrong', it's simpy
undefined. :)

-Mike
 
K

Ko van der Sloot

Gavin Deane wrote:

Of course I do. It was a simplified excerpt from a program that ran havoc.
In real life, the second argument was an index that at some point
reached npos.
Might be an odd thing to want to do in practice, but I'd be interested
in a definitive answer. My first thought was that maybe using npos as
the second argument to find has undefined behaviour, but I can't find
anything to back that up (doesn't mean it's not there of course). When
I compiled and ran the code using Visual Studio 2005, I got the output
I believe the OP ws expecting:

pos1=2
I expected this
I expected this

So I wonder whether the behaviour is undefined and I've just missed
where it says that, or has the OP found a compiler bug?

That is the point: My question boiles down to:
is calling find with npos as second argument legal, is it undefined? or
what?
I would expect (hope) that it is legal, and should return npos.
"because that is only reasonable thing to do"
Gavin Deane

Thanx
Ko
 
J

James Kanze

Not really. Presumably, in practice, the position is the
results of an earlier find. And it's rather convenient to not
have to check. Consider something like the following:

std::string
getInBraces(
std::string const& s )
{
size_t pos1 = s.find( '{' ) ;
size_t pos2 = s.find( '}', pos1 ) ;
return pos2 == std::string::npos
? std::string()
: s.substr( pos1 + 1, pos2 - pos1 - 1 ) ;
}

It looks reasonable to me, and having to check before the second
call to find would make the code (slightly) more complicated.
AFAIK, the second argument to find is an index into the string.
string::npos is not a valid index into a string, so I would expect the
same impact as specifying an out-of-bounds index to find.

What makes you say that? The standard doesn't place any such
restriction on it. In fact, the standard actually specifies as
a condition for not returning npos the fact that pos is in
range, which seems pretty clear to me. The argument is a
constraint on the return value; i.e. the value returned *must*
be <= pos (or npos, if a qualifying value cannot be found).
 
J

James Kanze

I believe it's implied in that the argument type is 'size_type'.

Why? What's implied in size_type is that the argument must be
representable in a size_type. Since npos also has size_type, it
must be representable in a size_type.
(My implementation's documentation describes 'size_type' as
"An unsigned integer type that can represent the number of elements
and indices in a string.")

Or npos, of course, since npos has the type size_type as well.
Other than that, the specification you quote says "can
represent", not is a valid index in a particular string.
Right. That's what npos is used for.

Amongst other things. It's also used to indicate "to the end",
e.g. as the second parameter in substr.
Undefined behavior is neither 'right' nor 'wrong', it's simpy
undefined. :)

But in this case, the behavior is clearly defined. The standard
places no precondition on npos (which it does in other cases),
and defines a set of post-conditions for the function: if the
return value is r, then r == npos || (r >= pos && s[ r ] == c).
The caller has met the pre-conditions (so there is no undefined
behavior), and the function has not fulfilled the
post-conditions. Looks like an error to me.
 
A

Alf P. Steinbach

* Ko van der Sloot:
is calling find with npos as second argument legal, is it undefined? or
what?

It's valid.

There are no restrictions on the second argument's value.
 
A

Andre Kostur

[snip example of using string::npos as second argument to string::find()]
What makes you say that? The standard doesn't place any such
restriction on it. In fact, the standard actually specifies as
a condition for not returning npos the fact that pos is in
range, which seems pretty clear to me. The argument is a
constraint on the return value; i.e. the value returned *must*
be <= pos (or npos, if a qualifying value cannot be found).

That's one way of looking at it. My first introduction to the find method
talks about starting its find at position pos. And since pos is an index
into the string, string::npos is an invalid index. size_type(-1) is way
beyond the end of the string, so it's not even one-past-the-end to make it
iterator-ish. But I can see the argument by reading the standard directly,
and that by passing any index beyond the end of the string would result in
a simple string::npos response.
 
A

Alf P. Steinbach

* Andre Kostur:
My first introduction to the find method
talks about starting its find at position pos. And since pos is an index
into the string, string::npos is an invalid index.

The standard doesn't use language like "starting" somewhere.

It merely states what the result should be.

There are no requirements on the second argument to 'find'.
 

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

Forum statistics

Threads
473,774
Messages
2,569,598
Members
45,159
Latest member
SweetCalmCBDGummies
Top