Results 1 to 17 of 17

Thread: VB String Functions

  1. #1
    Zaei
    Guest

    VB String Functions

    I wrote an implementation of several of the VB string functions in C++ yesterday, if anyone is interested. The ones I have done are:
    • InStr
    • Mid
    • Replace
    • TrimL
    • TrimR
    • Trim


    I also have functions to remove all but one space from a series of spaces, and one to remove tabs from a string:
    Code:
    If the input is "Hello      Zaei", the output would be "Hello Zaei", and, if the input is "Hello\tZaei", the output would be "Hello Zaei"
    I am also working on a split function. If anyone is interested, I will post the code (its on another computer, and I have to find a disk). Just let me know.

    Z.

  2. #2
    Monday Morning Lunatic parksie's Avatar
    Join Date
    Mar 2000
    Location
    Mashin' on the motorway
    Posts
    8,169
    Code:
    void split(vector<string> &v, const char *s, char c) {
    	string temp;
    
    	while(*s) {
    		if(*s == c) {
    			v.push_back(temp);
    			temp.erase();
    		} else
    			temp += *s;
    
    		++s;
    	}
    
    	if(!temp.empty()) v.push_back(temp);
    }
    Beat ya
    I refuse to tie my hands behind my back and hear somebody say "Bend Over, Boy, Because You Have It Coming To You".
    -- Linus Torvalds

  3. #3
    transcendental analytic kedaman's Avatar
    Join Date
    Mar 2000
    Location
    0x002F2EA8
    Posts
    7,221
    I'm happy to have a look and debate their efficiency etc.. If they're not for C style strings, then don't bother, anything else is inefficient
    Use
    writing software in C++ is like driving rivets into steel beam with a toothpick.
    writing haskell makes your life easier:
    reverse (p (6*9)) where p x|x==0=""|True=chr (48+z): p y where (y,z)=divMod x 13
    To throw away OOP for low level languages is myopia, to keep OOP is hyperopia. To throw away OOP for a high level language is insight.

  4. #4
    Monday Morning Lunatic parksie's Avatar
    Join Date
    Mar 2000
    Location
    Mashin' on the motorway
    Posts
    8,169
    Efficiency and resource-management are difficult to get a good compromise with.

    As it goes, using the standard string class is just as good, if not better, than doing it yourself using C-style strings since it inlines better and has all the extra allocation.
    I refuse to tie my hands behind my back and hear somebody say "Bend Over, Boy, Because You Have It Coming To You".
    -- Linus Torvalds

  5. #5
    transcendental analytic kedaman's Avatar
    Join Date
    Mar 2000
    Location
    0x002F2EA8
    Posts
    7,221
    Originally posted by parksie
    Efficiency and resource-management are difficult to get a good compromise with.

    As it goes, using the standard string class is just as good, if not better, than doing it yourself using C-style strings since it inlines better and has all the extra allocation.
    Not at all, C style strings doesn't nessesary mean that you use the c style string functions. the string class is dynamic and that already is a big big hog
    Use
    writing software in C++ is like driving rivets into steel beam with a toothpick.
    writing haskell makes your life easier:
    reverse (p (6*9)) where p x|x==0=""|True=chr (48+z): p y where (y,z)=divMod x 13
    To throw away OOP for low level languages is myopia, to keep OOP is hyperopia. To throw away OOP for a high level language is insight.

  6. #6
    Fanatic Member nabeels786's Avatar
    Join Date
    Jul 2001
    Location
    New York
    Posts
    919
    id be interested

    i hate that MFC junk, and when i write my own, i cant get it to work.

    im looking at parksies split function...*stares in amazement*
    Visit www.fragblast.com
    Gaming, forums, and a online RPG/Battle system




    (__Flagg) DOT NET? is this a Hindi Dating service?

  7. #7
    Zaei
    Guest
    I was going to do split using a char**, instead of a vector, as well as allowing a char* to be used as the delimiter. Ill get the code in a few minutes. I didnt try much to optimize these, but I did take care to use things like strlen() once per string, etc.

    Z.

  8. #8
    Zaei
    Guest
    Here ya go:
    Code:
    //strlib.cpp
    #include "strlib.h"
    #include <string.h>
    
    void mid(char** r, const char* src, long start, long len)
    {
    	if(len == 0) return;
    	*r = new char[len+1];
    	memcpy(*r, (void*)&(src[start]), len);
    	(*r)[len] = 0;
    	return;
    }
    
    long instr(long start, char* src, char* find)
    {
    	int i = 0;
    	int pos = start;
    	int len = strlen(find);
    	char* p = &(src[start]);
    	while(*p)
    	{
    		if(*p == find[i])
    			++i;
    		else
    			i = 0;
    		++pos;
    		if(i == len)
    			return pos-len+1;
    		
    		++p;
    	}
    	if(i == 0) return -1;
    	return -1;
    }
    
    void replace(char** r, char* src, char* find, char* repl)
    {
    	int i = 0;
    	char* tempBuff = NULL;
    	long p = 0;
    	while((p=instr(p+1, src, find)) != -1)
    	{
    		++i;
    		++p;
    	}
    	long finallen = strlen(src);
    	long findlen = strlen(find);
    	long repllen = strlen(repl);
    	finallen += repllen*i;
    	finallen -= findlen*i;
    	*r = new char[finallen+1];
    	(*r)[0] = NULL;
    	long lastPos = 0;
    	long thisPos;
    	for(int j = 0; j < i; ++j)
    	{
    		thisPos = instr(lastPos+1, src, find);
    		mid(&tempBuff, src, lastPos, thisPos - lastPos - 1);
    		strcat(*r, tempBuff);
    		strcat(*r, repl);
    		delete tempBuff;
    		lastPos = thisPos+findlen-1;
    	}
    	if(strlen(*r) == (unsigned int)finallen)
    		return;
    	strcat(*r, &(src[lastPos]));
    	return;
    }
    
    void triml(char** r, const char* src)
    {
    	long srclen = strlen(src);
    	for(int i = 0; i < srclen; ++i)
    	{
    		if(src[i] != ' ')
    		{
    			break;
    		}
    	}
    	*r = new char[srclen-i];
    	strcpy(*r, &(src[i]));
    	return;
    }
    
    void trimr(char** r, const char* src)
    {
    	long srclen = strlen(src);
    	for(int i = srclen-1; i > 0; --i)
    	{
    		if(src[i] != ' ')
    		{
    			++i;
    			break;
    		}
    	}
    	*r = new char[srclen-(srclen-i)+1];
    	memcpy(*r, src, srclen-(srclen-i));
    	(*r)[srclen-(srclen-i)] = 0;
    
    	return;
    }
    
    void trim(char** r, const char* src)
    {
    	trimr(r, src);
    	triml(r, *r);
    }
    ...
    Code:
    //strlib.h
    void mid(char** r, const char* src, long start, long len);
    long instr(long start, char* src, char* find);
    void replace(char** r, char* src, char* find, char* repl);
    void triml(char** r, const char* src);
    void trimr(char** r, const char* src);
    void trim(char** r, const char* src);
    Z.
    Attached Files Attached Files

  9. #9
    transcendental analytic kedaman's Avatar
    Join Date
    Mar 2000
    Location
    0x002F2EA8
    Posts
    7,221
    1. New without Delete:
    Allocating memory in one function and deallocating it in another is pretty dangerous thing to do, a user of your api's could assume that dynamical objects will allocate and deallocate automatically, and your code would be a permanent source of memory leaks. Thumb rule with dynamical memory allocation is that allocators deallocate (newer's deletes), another way at looking at it is that a specific function or object own's it's dynamic data and is responsible of proper deallocation.
    Just some OOP etiquette.
    2. those of your functions that returns a allocated pointer are restricted to output on the heap, although you'd have to face the complications of static size of buffers, allowing buffers on the stack is quite a big deal to a lot of programmers so your code will be a lot less usefull, if they wanted dynamical strings they would go with strings class anyways.
    3. instr, iterate another copy of find syncronous to p, and reset it to find if not equal, otherways if !*p then return. Also keep the othermost loop clean with only one if.

    I haven't looked at replace and the others yet, but will do tomorrow, too tired now.
    Use
    writing software in C++ is like driving rivets into steel beam with a toothpick.
    writing haskell makes your life easier:
    reverse (p (6*9)) where p x|x==0=""|True=chr (48+z): p y where (y,z)=divMod x 13
    To throw away OOP for low level languages is myopia, to keep OOP is hyperopia. To throw away OOP for a high level language is insight.

  10. #10
    Zaei
    Guest
    1. Yep, thats really the worst thing with this code, but, since these functions are for my own use, I dont care much =).

    2. Same as above =).

    3. So, saves me an strlen()?

    In the trim function, there should be a buffer copy, and delete *r between the trimr and triml calls. I think it will leak data otherwise (just noticed this one, not sure though (its late =)).

    Z.

  11. #11
    sql_lall
    Guest

    Question MID$ in C++

    Did you say you had made a C++ equivalen of the VB Mid$??
    If you have, is it possible to either post it, or send it to my email address ([email protected])

  12. #12
    transcendental analytic kedaman's Avatar
    Join Date
    Mar 2000
    Location
    0x002F2EA8
    Posts
    7,221
    it's abovemost in his code, but if you ask me, don't use it unless you are a C programmer (or "just know" what you're doing like Zaei claims to do =))
    I'd recommend the string class if you're just out after an easy interface
    Use
    writing software in C++ is like driving rivets into steel beam with a toothpick.
    writing haskell makes your life easier:
    reverse (p (6*9)) where p x|x==0=""|True=chr (48+z): p y where (y,z)=divMod x 13
    To throw away OOP for low level languages is myopia, to keep OOP is hyperopia. To throw away OOP for a high level language is insight.

  13. #13
    Zaei
    Guest
    Well, if i didnt know, it probably wouldnt work, eh? =).

    Z.

  14. #14
    Lively Member floppes's Avatar
    Join Date
    May 2001
    Location
    Darmstadt, Germany
    Posts
    99

    Thumbs up

    Yahooooo! That's what I've searched for!

    But only one problem:

    I want to use the instr function, but want to search in an Edit box whose data type is AnsiString, not char*...

    Is there a function to convert AnsiString to char*?

  15. #15
    Monday Morning Lunatic parksie's Avatar
    Join Date
    Mar 2000
    Location
    Mashin' on the motorway
    Posts
    8,169
    Use the Find member function (or find) on the AnsiString object you have.

    I think it's pretty much identical to the standard string actually.
    I refuse to tie my hands behind my back and hear somebody say "Bend Over, Boy, Because You Have It Coming To You".
    -- Linus Torvalds

  16. #16
    sql_lall
    Guest

    Question The string class

    You said - "Use the string class". What do you mean by that??

  17. #17
    Monday Morning Lunatic parksie's Avatar
    Join Date
    Mar 2000
    Location
    Mashin' on the motorway
    Posts
    8,169
    Code:
    #include <iostream>
    #include <string>
    
    using namespace std;
    
    int main() {
        string x;
        cin >> x;
    
        if(x.length() > 10)
            cout << x.substr(2, 5) << endl;
    
        return 0;
    }
    I refuse to tie my hands behind my back and hear somebody say "Bend Over, Boy, Because You Have It Coming To You".
    -- Linus Torvalds

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width