capture substring in the most efficient

M

Magix

hi,

let say I have this string

+CCED: "xxxxxxxxx", 333

What is the most efficient way to capture the string within the " " ? which
is xxxxxxxxx
xxxxxxxxx can be any string.

For loop solutions is not the option.

Thanks.
 
A

Alex Fraser

Magix said:
let say I have this string

+CCED: "xxxxxxxxx", 333

What is the most efficient way to capture the string within the " " ?
which is xxxxxxxxx
xxxxxxxxx can be any string.

For loop solutions is not the option.

There's no other practical way to do it. You could use sscanf() but that
will just use a loop internally.

Alex
 
R

Richard Bos

Alex Fraser said:
There's no other practical way to do it.

Sure there is. You could use strchr(). You might run into problems if
the string can contain internal '"'s, but you'll have to devise a
solution for that case anyway.
You could use sscanf() but that will just use a loop internally.

So does strchr(), but the loop in such functions is likely to be better
optimised than a normal for loop.

Richard
 
B

Bernhard Holzmayer

Richard said:
Sure there is. You could use strchr(). You might run into problems
if the string can contain internal '"'s, but you'll have to devise
a solution for that case anyway.
...
Good starting point. Let's do it this way:

Assuming that string is correct with respect to what you told us:
it really starts with +CC... and terminates with a ,<number>

char destination[maxLenOfString+1];
/* if maxLenOfString is unknown, use malloc() instead */

char * pstart = strchr(yourString,'"'); /* points to first " */
char * pstop = strrchr(yourString,'"'); /* points to last " */

size_t len = pstop-pstart; /* contains one " still */

strncpy (destination, pstart, len-1);
destination[len] = '\0';

( Code not checked )

Bernhard
 
B

Bernhard Holzmayer

Thomas said:
So, what is the difference between "for" loops and the
strchr function? Yes, I know that it is a library function
and on some platforms can use processor specific instructions,
but they both use repetition (looping). The OP wanted a
solution that doesn't use "for" loops.

I guessed that the OP didn't want to code explicit for loops,
because of poor performance, but that (hopefully optimized)
functions like strchr() would be acceptable.
One must use some kind of iteration to find the substring
unless:
1. The source string has fixed length fields.
or 2. The string is lexicographically order so that one
can use other search algorithms.

If the pattern, which the OP showed us, is fixed with respect
of the xxxx... part, it should be easy to just advance the start
pointer manually like pstart = &origin[9] or so.

But to find the length of the string, some sort of iterative or
recursive looping will certainly be unavoidable.

Once the length is known, and the pattern at the end,
again pstop could be found as something like
pstop=origin[lengthOfSTring-7].

I agree to you, that this always implies a sort of looping.

Depending on how the string was gathered,
there might be another chance if the OP could keep track of
the length (maybe a counter variable).
But that's implementation issue, not having to do with the
features of C.

Bernhard
 
T

Thomas Matthews

Bernhard said:
Richard Bos wrote:

Sure there is. You could use strchr(). You might run into problems
if the string can contain internal '"'s, but you'll have to devise
a solution for that case anyway.
...

Good starting point. Let's do it this way:

Assuming that string is correct with respect to what you told us:
it really starts with +CC... and terminates with a ,<number>

char destination[maxLenOfString+1];
/* if maxLenOfString is unknown, use malloc() instead */

char * pstart = strchr(yourString,'"'); /* points to first " */
char * pstop = strrchr(yourString,'"'); /* points to last " */

size_t len = pstop-pstart; /* contains one " still */

strncpy (destination, pstart, len-1);
destination[len] = '\0';

( Code not checked )

Bernhard

So, what is the difference between "for" loops and the
strchr function? Yes, I know that it is a library function
and on some platforms can use processor specific instructions,
but they both use repetition (looping). The OP wanted a
solution that doesn't use "for" loops.

One must use some kind of iteration to find the substring
unless:
1. The source string has fixed length fields.
or 2. The string is lexicographically order so that one
can use other search algorithms.

Perhaps, the OP should state why "for" loops must be avoided.

--
Thomas Matthews

C++ newsgroup welcome message:
http://www.slack.net/~shiva/welcome.txt
C++ Faq: http://www.parashift.com/c++-faq-lite
C Faq: http://www.eskimo.com/~scs/c-faq/top.html
alt.comp.lang.learn.c-c++ faq:
http://www.raos.demon.uk/acllc-c++/faq.html
Other sites:
http://www.josuttis.com -- C++ STL Library book
 
R

red floyd

Magix said:
hi,

let say I have this string

+CCED: "xxxxxxxxx", 333

What is the most efficient way to capture the string within the " " ? which
is xxxxxxxxx
xxxxxxxxx can be any string.

For loop solutions is not the option.

Thanks.

Why is a for loop not an option? If this is for work, then a solution
that works correctly and is reasonably efficient should be fine. If
this is for work, and your requirements are micro-managed to this
level so that you can't use for loops, I'd look for a new job.
Otherwise, this is homework.
 
A

Alan Balmer

I guessed that the OP didn't want to code explicit for loops,
because of poor performance, but that (hopefully optimized)
functions like strchr() would be acceptable.

My guess was that it's a homework question.
 
P

Peter Ammon

Magix said:
hi,

let say I have this string

+CCED: "xxxxxxxxx", 333

What is the most efficient way to capture the string within the " " ? which
is xxxxxxxxx
xxxxxxxxx can be any string.

For loop solutions is not the option.

Thanks.

How about:

char buff[] = "+CCED: \"xxxxxxxxx\", 333";
char* result = 1+strchr(buff, '"');
*strrchr(result, '"')=0;
 
M

Magix

I was trying to optimize the code performance, to see there is other option
better than "for" loop.
 
R

Richard Bos

Thomas Matthews said:
So, what is the difference between "for" loops and the
strchr function? Yes, I know that it is a library function
and on some platforms can use processor specific instructions,

That _is_ the difference.
but they both use repetition (looping). The OP wanted a
solution that doesn't use "for" loops.

strchr() is not a for loop. It does not require you to provide a counter
or a running pointer, and handle its initialisation, increment, and
boundary check. Internally, it may even, and in optimised libraries
probably will, not use for but DJNZ or whatever the local equivalent is.

Richard
 
C

Christopher Benson-Manica

Magix said:
I was trying to optimize the code performance, to see there is other option
better than "for" loop.

A wise man once spake the Two Rules of Optimization:

1) Don't do it.
2) (experts only) Don't do it yet.

In all likelihood, your compiler is perfectly capable of producing
efficient code from a for loop. There's usually very little to gain
from using obscure tricks in your code, and a lot of readability to
lose.
 
B

Bernhard Holzmayer

Peter said:
Magix said:
hi,

let say I have this string

+CCED: "xxxxxxxxx", 333

What is the most efficient way to capture the string within the "
" ? which is xxxxxxxxx
xxxxxxxxx can be any string.

For loop solutions is not the option.

Thanks.

How about:

char buff[] = "+CCED: \"xxxxxxxxx\", 333";
char* result = 1+strchr(buff, '"');
*strrchr(result, '"')=0;

If it was a homework, as Alan guesses, your solution will certainly
gain highscore. Really neat. Compact. I like it.

Almost nothing left for the optimizer - poor thing.

Bernhard
 
R

red floyd

Bernhard Holzmayer said:
Peter said:
Magix said:
hi,

let say I have this string

+CCED: "xxxxxxxxx", 333

What is the most efficient way to capture the string within the "
" ? which is xxxxxxxxx
xxxxxxxxx can be any string.

For loop solutions is not the option.

Thanks.

How about:

char buff[] = "+CCED: \"xxxxxxxxx\", 333";
char* result = 1+strchr(buff, '"');
*strrchr(result, '"')=0;

If it was a homework, as Alan guesses, your solution will certainly
gain highscore. Really neat. Compact. I like it.

Almost nothing left for the optimizer - poor thing.

Ok, how about:

char buff[] = "+CCED: \"xxxxxxxxx\", 333";
*strrchr(1+strchr(buff, '"'), '"')=0;
 
B

Bernhard Holzmayer

red floyd wrote:

How about:

char buff[] = "+CCED: \"xxxxxxxxx\", 333";
char* result = 1+strchr(buff, '"');
*strrchr(result, '"')=0;
....
Ok, how about:

char buff[] = "+CCED: \"xxxxxxxxx\", 333";
*strrchr(1+strchr(buff, '"'), '"')=0;

That's getting awkward. And the result gets lost.
The first one was better.
I don't like too condensed code, bc. it's less readable.
Should be up to the compiler to do such concentration.

However, the former solution was a good compromise.
The latter isn't.

Bernhard
 
R

red floyd

Bernhard Holzmayer said:
red floyd wrote:
[redacted]
That's getting awkward. And the result gets lost.
The first one was better.
I don't like too condensed code, bc. it's less readable.
Should be up to the compiler to do such concentration.

However, the former solution was a good compromise.
The latter isn't.

I was just having fun. To be honest (and I posted such above), I
thought that the requirement for "no for loops" was artificial and
either indicated inept micromanagement or homework. I said that he
should look for a solution that works first, and if a for loop does
the job reasonably efficiently, what's wrong with that?

Since not using for loops would tend to obfuscate the code (though the
strchr/strrchr solution is nice), I viewed this whole thing as
academic, anyways.
 

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,145
Messages
2,570,824
Members
47,370
Latest member
desertedtyro29

Latest Threads

Top