Jump to content
  • Advertisement

Archived

This topic is now archived and is closed to further replies.

ZealousElixir

substr

This topic is 5977 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hey guys. I was hacking around this afternoon and I came up with a pretty nifty implementation of a substr()-style function. I was wondering if there are any optimizations that could be easily made without the introduction of additional function calls. Anyway, here's the code. Let the flaming commence.
      
char *substr(char *base, int start, int length)
{
    int i = 0, j = 0, baselength = 0;
    
    while(base[i++] != '\0')
        baselength++;
    if(length > baselength)
        return "=NULL=";
    char* substring = new char[length + 1];
    for (i = start; i < length + start; i++, j++)
        substring[j] = base[i];
    substring[j] = '\0';
    return substring;
}
  
Thanks. Later, ZE. [EDIT: code formatting (still doesn't look right)] //email me.//zealouselixir software.//msdn.//n00biez.//
miscellaneous links
[if you have a link proposal, email me.] Edited by - zealouselixir on February 6, 2002 1:25:55 PM

Share this post


Link to post
Share on other sites
Advertisement
Why have it return ''null'' as a string if the length is longer than the base length? why not have it return the string up to the base length?

-Uhfgood

Share this post


Link to post
Share on other sites
Because I am the man.


Seriously, good idea. I'll fix that.

Later,
ZE.

P.S. Here's the fix:

    
if(length > baselength)
return "=NULL=";

// the above turns into...


if(length > baselength)
length = baselength;


In addition, if you want it to be as fool-proof as possible, add the following lines at the top:
  
if(!base)
return "\0";



//email me.//zealouselixir software.//msdn.//n00biez.//
miscellaneous links

[if you have a link proposal, email me.]



Edited by - zealouselixir on February 6, 2002 1:37:59 PM

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
your code won''t work. It may also cause core-dump. If you need help with your code, just say so.

Share this post


Link to post
Share on other sites
As far as I can tell, it won''t cause core dump, as long as you delete the substring when you''re finished with it. If you''re not concerned with memory leakage, you don''t even have to do that . Seriously though, if there are some issues I''m overlooking, tell me.

Later,
ZE.

//email me.//zealouselixir software.//msdn.//n00biez.//
miscellaneous links

[if you have a link proposal, email me.]

Share this post


Link to post
Share on other sites
The most obvious problem is that you don''t verify that start < baselength. The second problem is that it''s impossible to tell whether it''s ok to delete the returned string or not without examining the string (sometimes you return a string allocated with new, sometimes you return a constant string). A third (related) problem is that you can''t distinguish a success from a failure - consider if base actually contained the string "=NULL=".

-Mike

Share this post


Link to post
Share on other sites
Aiiight, here's version 3.

      
char *substr(char *base, int start, int length)
{
char *substring;
if(!base)
{
substring = new char[1];
substring[0] = '\0';
return substring;
}

int i = 0, j = 0, baselength = 0;

while(base[i++] != '\0')
baselength++;

if(length > baselength)
length = baselength;

if(start > baselength)
{
substring = new char[1];
substring[0] = '\0';
return substring;
}

substring = new char[length + 1];

for (i = start; i < length + start; i++, j++)
substring[j] = base[i];

substring[j] = '\0';

return substring;
}


Now you always have to delete the returned string, you can't go out of any boundaries, and (this wasn't a concern after version 2, but Mike didn't read all the follow-up posts) an empty string is simply returned when an error can't be recovered from. Now we just need optimizations

Later,
ZE.

//email me.//zealouselixir software.//msdn.//n00biez.//
miscellaneous links

[if you have a link proposal, email me.]

[EDIT: formatting and spelling]


Edited by - zealouselixir on February 6, 2002 9:25:53 PM

Share this post


Link to post
Share on other sites
1. Just return a null pointer instead of constructing a null string on the free store.
2. Prefer pre-increment to post increment, unless post-increment is necessary.
3. Reuse the standard library copy instead of writing your own.
4. Use the preprocessor to specify that the checks only be performed in debug mode (optional!).

  
#include <algorithm>
 
char* substr (char* base, int start, int length)
{
using std::copy;
 
if (!base) return 0;
 
#ifndef NDEBUG
{
int i = 0, baselength = 0;
 
while (base[i++] != ''\0'') ++baselength;
 
if (length > baselength) length = baselength;
if (start > baselength) return 0;
}
#endif // NDEBUG

 
char* substring = new char [length + 1];
 
char* begin = base + start;
char* end = being + length;
 
copy (begin, end, substring);
 
*end = ''\0'';
 
return substring;
}


I suppose that you could use std::memcpy to copy words at a time instead of bytes. std::memcpy should be highly optimized already. Outside of that, there isn''t much you can do to make your code execute faster.

Share this post


Link to post
Share on other sites
I think that''s a bad use of a debug-only check, as it will result in code that executes fine without any warnings in debug mode but crashes in release mode. Better to use assertions in debug mode if you want to insist that the function is given valid inputs. Otherwise choose between the range-checking that you have now and throwing exceptions when stuff is out of range.

[ MSVC Fixes | STL | SDL | Game AI | Sockets | C++ Faq Lite | Boost ]

Share this post


Link to post
Share on other sites

  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!