Author | Message | Time |
---|---|---|
iago | Just for fun, here's a couple of simple storm functions: [code].text:1503AA50 ; Returns the substring after the first occurance of the specific character in the string. Returns NULL if the character is not found. .text:1503AA50 .text:1503AA50 ; char *__fastcall SStrChr(char *str,char c) .text:1503AA50 public SStrChr .text:1503AA50 SStrChr proc near ; CODE XREF: SBmpSaveImageEx+6Dp .text:1503AA50 ; SBmpSaveImageEx+7Ap ... .text:1503AA50 mov eax, ecx ; Move the string into eax .text:1503AA52 test eax, eax ; Ensure that it's a valid character .text:1503AA54 jnz short SStrChrValidString .text:1503AA56 push ERROR_INVALID_PARAMETER ; dwErrCode .text:1503AA58 call SErrSetLastError .text:1503AA5D xor eax, eax .text:1503AA5F retn .text:1503AA60 ; --------------------------------------------------------------------------- .text:1503AA60 .text:1503AA60 SStrChrValidString: ; CODE XREF: SStrChr+4j .text:1503AA60 mov cl, [eax] ; Move the current character into ecx .text:1503AA62 test cl, cl ; Check if it's null .text:1503AA64 jz short SStrChrReturn0 ; If it's null, return 0 .text:1503AA66 .text:1503AA66 SStrChrTop: ; CODE XREF: SStrChr+20j .text:1503AA66 cmp cl, dl ; Compare the current character to the character we're looking for .text:1503AA68 jz short SStrChrReturn ; If they're equal, return the rest of the string .text:1503AA6A mov cl, [eax+1] ; ecx gets the next character into the string .text:1503AA6D inc eax ; eax goes to the next character .text:1503AA6E test cl, cl ; Check if the character is null .text:1503AA70 jnz short SStrChrTop .text:1503AA72 .text:1503AA72 SStrChrReturn0: ; CODE XREF: SStrChr+14j .text:1503AA72 xor eax, eax .text:1503AA74 .text:1503AA74 SStrChrReturn: ; CODE XREF: SStrChr+18j .text:1503AA74 retn .text:1503AA74 SStrChr endp [/code] [code] .text:1503AA80 ; Exported entry 570. .text:1503AA80 ; Exported entry 572. .text:1503AA80 .text:1503AA80 .text:1503AA80 ; Returns the address of the final occurance of c within the string str. If it is not found, NULL is returned. .text:1503AA80 .text:1503AA80 ; char *__fastcall SStrChrR(const char *str,char c) .text:1503AA80 public SStrChrR .text:1503AA80 SStrChrR proc near ; CODE XREF: sub_15001420+82p .text:1503AA80 ; sub_150024C0+D3p ... .text:1503AA80 test ecx, ecx ; Make sure we have a non-null string .text:1503AA82 jnz short SStrChrValidParameter .text:1503AA84 push ERROR_INVALID_PARAMETER ; dwErrCode .text:1503AA86 call SErrSetLastError .text:1503AA8B xor eax, eax ; return 0 .text:1503AA8D retn .text:1503AA8E ; --------------------------------------------------------------------------- .text:1503AA8E .text:1503AA8E SStrChrValidParameter: ; CODE XREF: SStrChrR+2j .text:1503AA8E push ebx .text:1503AA8F mov bl, [ecx] ; Move the first character in ecx to bl .text:1503AA91 push esi .text:1503AA92 xor esi, esi ; Clear esi .text:1503AA94 test bl, bl ; Check if the character is null .text:1503AA96 jz short SStrChrReturnEsi .text:1503AA98 .text:1503AA98 SStrChrTopLoop: ; CODE XREF: SStrChrR+24j .text:1503AA98 cmp bl, dl ; Compare the character to the character we're searching for .text:1503AA9A jnz short SStrChrNotEqual .text:1503AA9C mov esi, ecx ; If they're equal, move the character here .text:1503AA9E .text:1503AA9E SStrChrNotEqual: ; CODE XREF: SStrChrR+1Aj .text:1503AA9E mov bl, [ecx+1] ; Set the current character to the next character .text:1503AAA1 inc ecx ; Go to the next character .text:1503AAA2 test bl, bl ; Loop as long as we aren't at null .text:1503AAA4 jnz short SStrChrTopLoop ; Compare the character to the character we're searching for .text:1503AAA6 .text:1503AAA6 SStrChrReturnEsi: ; CODE XREF: SStrChrR+16j .text:1503AAA6 mov eax, esi .text:1503AAA8 pop esi .text:1503AAA9 pop ebx .text:1503AAAA retn .text:1503AAAA SStrChrR endp [/code] One question I have is, why do they each have 2 ords? Is there some reason for that? | May 15, 2004, 1:36 AM |
Eibro | I don't have a lot of experience doing this, but here's my go at converting it to C [code]char* __fastcall SStrChrR( const char* str, char c ) { if ( str == NULL ) { SSetLastError( ERROR_INVALID_PARAMETER ); return NULL; } char* found = NULL; while ( *str != NULL ) { if ( c == *str ) found = str; } return found; } char* __fastcall SStrChr( char* str, char c ) { if ( str == NULL ) { SSetLastError( ERROR_INVALID_PARAMETER ); return NULL; } while ( *str != c || *str != NULL ) ++str; return str; }[/code] | May 15, 2004, 4:28 AM |
iago | I believe your while loop in the SStrChr should be &&, not || | May 15, 2004, 8:20 AM |
Moonshine | [quote author=Eibro[yL] link=board=7;threadid=6808;start=0#msg60202 date=1084595309] I don't have a lot of experience doing this, but here's my go at converting it to C [code]char* __fastcall SStrChrR( const char* str, char c ) { if ( str == NULL ) { SSetLastError( ERROR_INVALID_PARAMETER ); return NULL; } char* found = NULL; while ( *str != NULL ) { if ( c == *str ) found = str; } return found; } char* __fastcall SStrChr( char* str, char c ) { if ( str == NULL ) { SSetLastError( ERROR_INVALID_PARAMETER ); return NULL; } while ( *str != c || *str != NULL ) ++str; return str; }[/code] [/quote] You missed the char* incrementation in your first function. Here's what I got: [code] char * __fastcall SStrChr( char * str, char ch ) { if (!str) { //SErrSetLastError(ERROR_INVALID_PARAMETER); return (NULL); } for (int i = 0; *str; i++, *str++) if (*str == ch) return (str); return (NULL); } const char * __fastcall SStrChrR( const char * str, char ch ) { if (!str) { //SErrSetLastError(ERROR_INVALID_PARAMETER); return (NULL); } int i; const char * pRet = NULL; for (i = 0; *str; i++, *str++) if (*str == ch) pRet = str; return (pRet); } [/code] Edit: Iago, are you SURE the second function isn't returning a const char*? It doesn't really make sense otherwise. | May 15, 2004, 9:13 PM |
Adron | I don't see why a strchr function should return a const char* instead of a char*. Makes much more sense to return a char*. The found variable going out of scope is not a problem. | May 15, 2004, 9:20 PM |
Moonshine | I forgot that found was pointing to the parameter itself -- my bad. Anyways, SStrChrR should definitely be returning a const char * if the parameter is const char *. Otherwise, you'd need to const_cast<>() it at return, and that's dangerous. | May 15, 2004, 9:32 PM |
Adron | [quote author=Moonshine link=board=7;threadid=6808;start=0#msg60284 date=1084656762] I forgot that found was pointing to the parameter itself -- my bad. Anyways, SStrChrR should definitely be returning a const char * if the parameter is const char *. Otherwise, you'd need to const_cast<>() it at return, and that's dangerous. [/quote] Ah. I got confused because you said the second function, and in the C++ post, it's the argument of the first function that is const char *. Either way; I think he put a const on it that shouldn't be there. It's very useful to have strchr and strrchr return a char *. | May 15, 2004, 10:09 PM |
Maddox | [quote author=Moonshine link=board=7;threadid=6808;start=0#msg60274 date=1084655629] You missed the char* incrementation in your first function. Here's what I got: [code] char * __fastcall SStrChr( char * str, char ch ) { if (!str) { //SErrSetLastError(ERROR_INVALID_PARAMETER); return (NULL); } for (int i = 0; *str; i++, *str++) if (*str == ch) return (str); return (NULL); } const char * __fastcall SStrChrR( const char * str, char ch ) { if (!str) { //SErrSetLastError(ERROR_INVALID_PARAMETER); return (NULL); } int i; const char * pRet = NULL; for (i = 0; *str; i++, *str++) if (*str == ch) pRet = str; return (pRet); } [/code] Edit: Iago, are you SURE the second function isn't returning a const char*? It doesn't really make sense otherwise. [/quote] More like [code] char * __fastcall SStrChr( char * str, char ch ) { if (!str) { //SErrSetLastError(ERROR_INVALID_PARAMETER); return (NULL); } while(*str) { if (*str == ch) return (str); str++; } return (NULL); } [/code] | May 15, 2004, 10:33 PM |