what would the equivalent of Left, Right, Mid(Mid$) be in C++?
Len is strlen right?
thanks
Printable View
what would the equivalent of Left, Right, Mid(Mid$) be in C++?
Len is strlen right?
thanks
You use strncpy() to get out a part of a string, into another.
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.
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;
}
great thanks =)
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.
nono, everything is pure API..=)
are there such functions with the string class?
thanks
Yes. string::substr :)
how would i translate this to c++
thanksCode:Dim sBuf As String
Dim iSize As String
Dim iRetCode As Integer
sBuf = Space$(8192)
iSize = Len(sBuf)
jim, the "left" function gives me an illegal operation =(
where do i find the "substr" function??
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();
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.
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:#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 may want to do something like that, so you need worry about fewer things.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;
}
thanks jim =)
parksie, i tried doing the space thing like that:
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...Code:char *buf;
for(int i=0; i<5; i++)
{
strcat(boom, " ");
}
void main()
{
cout << boom << endl;
}
it gives me an illegal operation.
thanks
how would i write an equivalent to Space in VB, without using the string class..i mean:
thanksCode:string s; //not using string
char *str; //but using char *
please? when i do it i get an illegal operation..=(
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:
I use calloc as it does the "zout" thing as well as allocate memory. Most folks starting out seem to want to useCode:void glob_init(void){
stringspace = (char *)calloc(BUFSIZ+1);
atexit(glob_free);
}
void glob_free(void){
free(stringspace); // or whatever else is global
}
char stringapce[BIG];
-instead of calloc; that's the reason for the zout macro.
Amon -
spaces
Since I got you in trouble before - suppose you have: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
}
Looks good, right? Wrong.Code:char tmp[100];
int i;
spaces(tmp,100);
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);
Jim -
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.Quote:
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:
Instead of global variables, have them in your main proc. That won't expose them unnessesarily.
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?Quote:
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 - You could use memset as well, I replied to your other thread.
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 =)
when i do this
i dont get an erro though..it works fine...should i still doPHP Code:void main()
{
char buf[10];
int i;
spaces(buf, sizeof(buf));
cout << buf << endl;
}
or is it not necessary?Code:sizeof(buf) - 1
thanks
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.
great thanks =)
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 ;)
lol thanks for the tip...=)
one more thing
is the equivalent to InStr in VB -> strchr in C++?Code:iPos = InStr(sValue, Chr$(0))
thanks
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.
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.
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
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:
Versus this block without globals....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];
}
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....
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.