|
-
Oct 4th, 2001, 11:17 PM
#1
Thread Starter
Hyperactive Member
string manipulations
what would the equivalent of Left, Right, Mid(Mid$) be in C++?
Len is strlen right?
thanks
Amon Ra
The Power of Learning.
-
Oct 5th, 2001, 06:30 AM
#2
transcendental analytic
You use strncpy() to get out a part of a string, into another.
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.
-
Oct 5th, 2001, 07:25 AM
#3
I'll post C versions of this when I get to work. The stdlib & string operations in C are rudimentary. You have to implement your own versions of this stuff.
The CString class supports
::Left, ::Right, and ::Mid operations
Go into help- CString class members there's loads of them.
-
Oct 5th, 2001, 08:59 AM
#4
Here are some vanilla c versions of string things:
Code:
void trim(char *t){
rtrim(t);
if (strlen(t))
ltrim(t);
}
void rtrim(char *t){
char *buf;
if (!strlen(t) ) return;
buf = t;
buf += strlen(t) -1;
while (*buf == ' ' && strlen(t) )
*buf-- = '\0';
}
void ltrim(char *t){
char tmp[128];
char *buf;
if (!strlen(t) ) return;
strcpy(tmp,t);
buf=tmp;
while (*buf == ' ' && strlen(buf)) *buf++;
strcpy(t,buf);
}
char *right(char *t,int len){
char *buf;
int i;
if (strlen(t) <=len)
return t;
buf = t;
buf +=strlen(t);
for (i=0;i<len;i++) buf--;
return buf;
}
char *left(char *t,int len){
char *buf;
if (strlen(t)<=len)
return t;
buf = t;
buf += len;
*buf = '\0';
return t;
}
char *mid(char *t,int start, int len){
char *buf;
int i;
if (!strlen(t) )
return t;
buf = t;
buf +=start;
buf = left(buf,len);
return buf;
}
-
Oct 5th, 2001, 11:19 AM
#5
Thread Starter
Hyperactive Member
Amon Ra
The Power of Learning.
-
Oct 5th, 2001, 11:31 AM
#6
Monday Morning Lunatic
PS: If you don't want to do it in C, then I would suggest using string unless it absolutely has to work with MFC.
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
-
Oct 5th, 2001, 11:39 AM
#7
Thread Starter
Hyperactive Member
nono, everything is pure API..=)
are there such functions with the string class?
thanks
Amon Ra
The Power of Learning.
-
Oct 5th, 2001, 11:41 AM
#8
Monday Morning Lunatic
Yes. string::substr
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
-
Oct 5th, 2001, 08:47 PM
#9
Thread Starter
Hyperactive Member
how would i translate this to c++
Code:
Dim sBuf As String
Dim iSize As String
Dim iRetCode As Integer
sBuf = Space$(8192)
iSize = Len(sBuf)
thanks
Amon Ra
The Power of Learning.
-
Oct 5th, 2001, 09:50 PM
#10
Thread Starter
Hyperactive Member
jim, the "left" function gives me an illegal operation =(
Amon Ra
The Power of Learning.
-
Oct 5th, 2001, 10:06 PM
#11
Thread Starter
Hyperactive Member
where do i find the "substr" function??
Amon Ra
The Power of Learning.
-
Oct 6th, 2001, 03:15 AM
#12
Monday Morning Lunatic
Code:
string sBuf;
// Couldn't think of another way off the top of my head
for(int i = 0; i < 8192) sBuf += " ";
int iSize = sBuf.length();
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
-
Oct 6th, 2001, 06:51 AM
#13
Oh. Strings aren't initialized, you have to do that yourself. All of these functions depend on there being a terminating NULL char.
If fact, good programming practice is to init everything
int blah = 0;
struct z mystruct;
zout(mystruct);
char tmp[100];
zout(tmp); etc.
I don't do a lot of standard good stuff in examples because I'm lazy.
Code:
#define zout(x) memset(&x,'\0',sizeof(x) )
char tmp[20];
printf("%s\n",left(tmp,3)); <<<< may give error
zout(tmp);
printf("%s\n",left(tmp,3) ); <<< okay
You do realize that the version you used of "left" actually changes the original string? BASIC doesn't change the original string. What is done a lot of languages is to create so-called string space kinda like this (with a lot of details left out):
Code:
char stringspace[BIG]; << global area - BIG is some big number
BIG is often set to BUFSIZ + 1
// non-destructive left
char *left(char *t,int len){
char *buf;
strcpy(stringspace,t);
if (strlen(t)<=len)
return t;
buf = stringspace;
buf += len;
*buf = '\0';
return stringspace;
}
You may want to do something like that, so you need worry about fewer things.
-
Oct 6th, 2001, 11:02 AM
#14
Thread Starter
Hyperactive Member
thanks jim =)
parksie, i tried doing the space thing like that:
Code:
char *buf;
for(int i=0; i<5; i++)
{
strcat(boom, " ");
}
void main()
{
cout << boom << endl;
}
it doesn't work...i wanna try not using the string class, cuz for the other functions i haven't..its good to know though...
it gives me an illegal operation.
thanks
Amon Ra
The Power of Learning.
-
Oct 6th, 2001, 12:48 PM
#15
Thread Starter
Hyperactive Member
how would i write an equivalent to Space in VB, without using the string class..i mean:
Code:
string s; //not using string
char *str; //but using char *
thanks
Amon Ra
The Power of Learning.
-
Oct 6th, 2001, 01:43 PM
#16
Thread Starter
Hyperactive Member
please? when i do it i get an illegal operation..=(
Amon Ra
The Power of Learning.
-
Oct 7th, 2001, 07:37 AM
#17
Kedaman -
you're right - what I"m trying to show is that standard C strings
have to have a terminating NULL. They are not created that way.
You shouldn't just randomly init variables. Init them once in the module that declares them (constructor), and leave it at that.
For global variables, specifically call a function like glob_init:
Code:
void glob_init(void){
stringspace = (char *)calloc(BUFSIZ+1);
atexit(glob_free);
}
void glob_free(void){
free(stringspace); // or whatever else is global
}
I use calloc as it does the "zout" thing as well as allocate memory. Most folks starting out seem to want to use
char stringapce[BIG];
-instead of calloc; that's the reason for the zout macro.
Amon -
spaces
Code:
// note: this does not check for the validity of len
void spaces(char *t, int len){
char *buf;
int i=0;
buf=t;
for(i=0;i<len;i++){
*buf = ' ';
buf++;
}
*buf='\0'; // add terminal NULL
}
Since I got you in trouble before - suppose you have:
Code:
char tmp[100];
int i;
spaces(tmp,100);
Looks good, right? Wrong.
tmp only holds 99 chars. The first byte of i will be overwritten.
C usually allocates memory for local function variables contiguously. That means if you ask the stupid spaces function to blank out 105 chars in spaces() it will try to do that as well. And it will nuke anything declared after tmp. This is usually what causes those illegal operations you are getting. You can overwrite code, file buffers, and other stuff the same way too.
safe use of spaces:
spaces(sizeof(tmp) - 1);
-
Oct 7th, 2001, 08:02 AM
#18
transcendental analytic
Jim -
Originally posted by jim mcnamara
You shouldn't just randomly init variables. Init them once in the module that declares them (constructor), and leave it at that.
For global variables, specifically call a function like glob_init:
I have local variables, member variables, but seldom global variables, so seldom i could almost say never. If I init my variables, I do it where they are needed.
Instead of global variables, have them in your main proc. That won't expose them unnessesarily.
I use calloc as it does the "zout" thing as well as allocate memory. Most folks starting out seem to want to use
char stringapce[BIG];
-instead of calloc; that's the reason for the zout macro.
calloc allocates on the heap right? If that's the case then you probably use zout on stack variables, more specifically those that obviously won't initialize themselves. I haven't used calloc before so do you mean it fills the memory with 0es after it's allocation?
Amon - You could use memset as well, I replied to your other thread.
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.
-
Oct 7th, 2001, 11:03 AM
#19
Thread Starter
Hyperactive Member
thank you very much guys..i appreciate..=)
just one question, is it just me, or is the space function in VB suppoesed to overwrite the string with ' ' ?
thanks again =)
Amon Ra
The Power of Learning.
-
Oct 7th, 2001, 11:09 AM
#20
Thread Starter
Hyperactive Member
when i do this
PHP Code:
void main()
{
char buf[10];
int i;
spaces(buf, sizeof(buf));
cout << buf << endl;
}
i dont get an erro though..it works fine...should i still do
or is it not necessary?
thanks
Amon Ra
The Power of Learning.
-
Oct 7th, 2001, 11:46 AM
#21
transcendental analytic
space in vb returns a string with the spaces, in most cases that's not too usefull. More generic is to fill something with spaces, or better any character like memset does. If you want separate strings, you use strncopy, and then memset.
you should use sizeof(buf) - 1 because it puts the terminating null after the last char.
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.
-
Oct 7th, 2001, 12:24 PM
#22
Thread Starter
Hyperactive Member
Amon Ra
The Power of Learning.
-
Oct 7th, 2001, 12:38 PM
#23
transcendental analytic
btw if you write past the end of an array, it is a bug, because you might overwrite something else (the compiler is unable to detect these, it's runtime specific). If you're lucky the app just crashes, if not, it could change other variables causing unexpected results, like your harddrive getting formatted
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.
-
Oct 7th, 2001, 05:01 PM
#24
Thread Starter
Hyperactive Member
lol thanks for the tip...=)
one more thing
Code:
iPos = InStr(sValue, Chr$(0))
is the equivalent to InStr in VB -> strchr in C++?
thanks
Amon Ra
The Power of Learning.
-
Oct 7th, 2001, 05:21 PM
#25
transcendental analytic
Yep, you would do for instance
char* p = strchr(mycstring,0);
but the c strings always terminate with 0 so strlen(mycstring); will also work.
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.
-
Oct 7th, 2001, 07:48 PM
#26
strchr() is the generic version of looking in a string-
but note - you wanted the first occurrence of \0 - which
in C is really strlen()
memset is easier to use - however the version spaces I gave you is specific version of how memset is implemented in gcc.
FYI -
strstr() is the C version of instr, it will work with single chars as well.
The examples I gave you are all pointer based. If you don't understand 'em Kedaman suggested memset(), which is just fine.
-
Oct 7th, 2001, 07:54 PM
#27
Thread Starter
Hyperactive Member
nono thanks..i do understand how they work with pointers..i just wanted to make sure which was the equivalent of InStr..so it is strstr?
thanks
Amon Ra
The Power of Learning.
-
Oct 7th, 2001, 08:10 PM
#28
Oh. PS: Kedaman's suggestion about memset() is a good one, especially if you are uncomfortable with pointers. In C you need to realize there are VERY FEW functions compared to VB. Probably about 10%. Everything else you do yourself. I've got a library of routines that I've had for... too long. I just re-use them.
Ked -
calloc() is like malloc() and then memset() with 0's.
Global variables are more efficient, but they do tend to screw up
data abstraction. I just finshed a 20K line program the other day. Virtually all the production code I've seen makes use of globals. This one has about 20 global variables.
Dont' believe me (about the speed part)?
Try timing like GetTickCount() on these two code hunks:
Code:
char *a="ABCDEFGHIJKMLNOPRSTUVXWYX1234567890";
char *b= "0987654321";
char tmp[500];
void test(){
long i,start;
char *t;
start = GetTickCount();
for (i=0;i<200000;i++){
testbed(t);
}
printf("%ld\n", GetTickCount() - start);
}
void testbed(char *t){
memset(tmp,'\0',sizeof(tmp) );
strcat(tmp,a);
strcat(tmp,b);
*t= tmp[1];
}
Versus this block without globals....
Code:
void test(){
long i,start;
char *t;
start = GetTickCount();
for (i=0;i<200000;i++){
testbed(t);
}
printf("%ld\n", GetTickCount() - start);
}
void testbed(char *t){
char *a="ABCDEFGHIJKMLNOPRSTUVXWYX1234567890";
char *b= "0987654321";
char tmp[500];
memset(tmp,'\0',sizeof(tmp) );
strcat(tmp,a);
strcat(tmp,b);
*t= tmp[1];
}
Please let me know what you find on your machine....
-
Oct 8th, 2001, 04:30 AM
#29
transcendental analytic
Global VS Local
Jim - I had to do some modifications of your code. First off the wild pointer t made it crash, it's now a local variable and i pass it's address. Next unlike the global version, the strings are initialized each time in the testbed method, totally unnessesarily. Make them const and you'll see the time gap between is eliminated. You may be right that access of nonstatic member variables of classes can be slower, but insignificantly, local and global variable should not be different, and member access should be restricted by using local buffers at time critical processes.
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.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|