Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon.

Pages: 1-

C++ String Compare

Name: Anonymous 2011-09-21 16:58

Sup niggaz. This shit is throwing an exception when it gets to this code in runtime. Any ideas?

- Assume "in" is a string comprised of "http://google.com/derp"
- found is a link found, can be w/e string

As far as I can tell, it explodes on the line where I'm trying to compare the 2 strings, as for some reason the loop is not concatenating the compare string - any idea why that is?


bool isLinkExternal(string in, string found)
{
    string compare = "";
    bool isExternal = false;

    //Get domain of original link
    for (int i = 6; in[i] != '/' ; i++)
    {
        compare += in[i];
    }
   
    //Compare domains of original and found links
    if (found.compare(7,compare.length(),compare) == 0)
        isExternal = true;

    return isExternal;
}


The way I see it, the loop starts at 7 chars in, which excludes the initial "http://". It should then keep going, concatenating each char into the compare string until a slash is found. The last bit is to compare that string to the portion of the string "in" of the same length, starting at the same point (7 chars in, for length of compare)

Name: Anonymous 2011-09-21 17:01

[code]strstr(in, "http://")

Name: Anonymous 2011-09-21 17:04

How some doing some [s]printf[/s] couts (LOL) to see the value of your compare variable before the comparison.

Name: Anonymous 2011-09-21 17:04

>>2
lolwat?

this function is receiving 2 strings:
in - a string containing the original link entered by user
found - a string containing a link found by the program, compared to the original link, in order to determine if it's an external site (not perfect, but this idea works for what I'm trying to accomplish..if it works.)

Name: tdavis 2011-09-21 17:05

NSA or somebody was bitching about ring-0 only, so I promised no networking to stay out of trouble.  A commodore 64 is what I had in mind, functionally, but faster!

My links are all to local files and I invented different link types.  FI is file,FL file line number, FF string in file, possibly N into it, BF is bible link, MN is compiler symbol table, HI is help index, might have more.

Name: Anonymous 2011-09-21 17:07

>>3
I've actually tried tossing in a few couts to see if compare is being added to, but I'm not even seeing that anything is being added to it at all.

Name: Anonymous 2011-09-21 17:13

>>5
NSA or somebody was bitching about ring-0 only
I actually laughed.

Name: Anonymous 2011-09-21 17:29

compile with -g and inspect the variables at runtime with gdb

Name: tdavis 2011-09-21 17:38

At Ticketmaster they had bare metal down to an art.  They did a VAX operating system, network device software, printers, bar code readers, all on bare metal.

I learned the first thing you make is a debugger.  You swap-in/out your break points when you do context changes.  LoseThos debugger is unpleasant because of 64-bit addresses -- no fun for typing.  Fuck that!

Name: Anonymous 2011-09-21 18:21

SOMETHING about mutable string objects or some shit like that. Who the fuck knows. C++ / java are faggot languages that CREATE problems.

Name: Anonymous 2011-09-21 18:53

You're passing parameters which are out of bound to the compare member function, you didn't properly read the documentation.

What you're doing is also dangerous by assuming that the strings are at lesat 6/7 characters long. Furthermore, you're doing a bunch of unnecessary copying of data. You are a bad programmer.

Here, I've fixed it for you.


typedef std::pair<size_t, size_t> string_bounds;

inline string_bounds getUrlDomainBounds(std::string const& url) {
    size_t start = (url.compare(0, 6, "http://") == 0) ? 6 : 0;
    size_t end = url.find_first_of('/', start);
    if (end == std::string::npos) {
        end = url.size() - start;
    }
    return std::make_pair(start, end);
}

bool isLinkExternal(std::string const& in, std::string const& found) {
    string_bounds in_bounds = getUrlDomainBounds(in);
    string_bounds found_bounds = getUrlDomainBounds(found);
    return in.compare(in_bounds.first, in_bounds.second, found, in_bounds.first, in_bounds.second) == 0;
}

Name: Anonymous 2011-09-21 18:56

>>11
Wait, there was a small but in getUrlDomainBounds, mixed up an offset for a character count.

inline string_bounds getUrlDomainBounds(std::string const& url) {
    size_t start = (url.compare(0, 6, "http://") == 0) ? 6 : 0;
    size_t end = url.find_first_of('/', start);
    if (end == std::string::npos) {
        end = url.size();
    }
    return std::make_pair(start, end - start);
}

Name: Anonymous 2011-09-21 18:59

>>11
And you want to change the last line of isExternal, it should be returning true if the domains aren't the same I'm presuming.

return in.compare(in_bounds.first, in_bounds.second, found, in_bounds.first, in_bounds.second) != 0;

Name: Anonymous 2011-09-21 19:03

>>10
Who the fuck knows.
People who aren't grossly incompetent.

Name: Anonymous 2011-09-22 0:19

>>11
"you're doing a bunch of unnecessary copying of data. You are a bad programmer."

Thanks Captain Obvious.

As far as assumption of minimum string length, for the purpose of this program, all related strings are pretty much guaranteed to be at least 7 characters long by this point in the program.


>>13
Overlooked that, thanks

Name: Anonymous 2011-09-22 1:43

Figured it out, the problem was that I was using array values for the in string, when I should have been using the values for the found string:



bool isLinkExternal(string in, string found)
{
    const int len = found.length();
    int slashcount = 0;
    string comp;

    //Parse found link
    for (int i = 0; i != len; i++)
    {
        //Increment when slash found
        if (found[i] == '/')
        {
            slashcount++;
        }

        if (slashcount < 3)
        {
            comp += found[i];
        }
    }

    //Compare domains of original and found links
    if (in.compare(0,comp.length(),comp) == 0)
        return false;
    else
        return true;
}

Name: Anonymous 2011-09-22 2:33

>>11,12
holy shit enterprise bloat

>>16

if (in.compare(0,comp.length(),comp) == 0)
  return false;
else
  return true;


Did you just finish CS101?

You do not need to do ANY copying of data around whatsoever. The solution would look something like this (not tested, written in 30 seconds, no warranties expressed or implied, etc.)

int isLinkExternal(char *in, char *found) {
 return !strncmp(in+7,found+7,strchr(in+7,'/')-in);
}


...and people wonder why their goddamn browser is so slow.

Name: Anonymous 2011-09-22 3:03

>>17
Further, you might ask "is there really any difference?"

Here is how your version of the function starts:
00000004         push    0FFFFFFFFh
00000006         push    offset $L8902
0000000B         mov     eax, dword ptr fs:__except_list
00000011         push    eax
00000012         mov     dword ptr fs:__except_list, esp
00000019         sub     esp, 14h
0000001C         push    ebx
0000001D         push    ebp
0000001E         push    esi
0000001F         push    edi
00000020         mov     al, [esp+30h+arg_10]
00000024         mov     edi, [esp+30h+arg_18]
00000028         xor     ebx, ebx
0000002A         lea     ecx, [esp+30h+var_1C]
0000002E         push    ebx
0000002F         mov     [esp+34h+var_4], 1
00000037         xor     ebp, ebp
00000039         mov     [esp+34h+var_1C], al
0000003D         call    std::basic_string<char,std::char_traits<char>,std::allocator<char>>::_Tidy(bool)
00000042         xor     esi, esi
00000044         cmp     edi, ebx
00000046         mov     byte ptr [esp+30h+var_4], 2
0000004B         jz      short loc_0_BD
0000004D         mov     ecx, [esp+30h+arg_14]
00000051 loc_0_51:
00000051         cmp     [esp+30h+arg_18], esi
00000055         jb      short loc_0_6D
00000057         cmp     ecx, ebx
00000059         jz      short loc_0_6D
0000005B         lea     ecx, [esp+30h+arg_10]
0000005F         call    std::basic_string<char,std::char_traits<char>,std::allocator<char>>::_Freeze(void)
00000064         mov     ecx, [esp+30h+arg_14]
00000068         lea     eax, [ecx+esi]
0000006B         jmp     short loc_0_72

...and on and on, for 420 bytes in this function. That's not all either, there's a bunch of other functions that bring the total to over 1600 bytes.

So you say "1.6KB is nothing these days"... let's compare with my version:

00000000         push    esi
00000001         push    edi
00000002         mov     edi, [esp+arg_0]
00000006         push    2Fh ; '/'
00000008         lea     esi, [edi+7]
0000000B         push    esi
0000000C         call    _strchr
00000011         sub     eax, edi
00000013         push    eax
00000014         mov     eax, [esp+0Ch+arg_4]
00000018         add     eax, 7
0000001B         push    eax
0000001C         push    esi
0000001D         call    _strncmp
00000022         add     esp, 14h
00000025         neg     eax
00000027         sbb     eax, eax
00000029         pop     edi
0000002A         inc     eax
0000002B         pop     esi
0000002C         retn


That's it. 44 bytes. We both essentially wrote code to do the same thing, but you ended up needing 68 times the memory to do it (and that's not including the allocation of the extra string in your version.)

"is there really any difference?" See for yourself.

I hope this little example has given you an appreciation for what can happen if you aren't careful with how you design programs.

Name: Anonymous 2011-09-22 4:42

>>18

lol wow

when was the last time you got laid?

Name: Anonymous 2011-09-22 4:44

>>19
How's that related to the topic? Are you trying to insult em because he made your retardness even more obvious?

Name: Anonymous 2011-09-22 5:29

>>20

you sound offended

did I hit a nerve?

Name: Anonymous 2011-09-22 5:30

>>21
Why don't you use proper punctuation?

Name: Anonymous 2011-09-22 6:45

I must put a stop to the homosexual courtship going on in here because fucking retards is against the law.

Name: Anonymous 2011-09-22 9:36

>>1-23
u mad

Don't change these.
Name: Email:
Entire Thread Thread List