Click to See Complete Forum and Search --> : how to manipulate char* type in C ?


namgor
06-24-2002, 11:19 PM
input: char* a = " i love sharky forum ";
output" char* b = "i love sharky forum";

how do I write a little function to perform manipulation on a to make it become b ??

i tried the following, but returned segmentation fault:


char* trims(char* input) {
char ret[500];
int i = 0;

for (i = 0; i < strlen(input); i++) {
if (input[i]!=' ') continue;
strcat (ret, input[i]);
}

return ret;
}


Thx~! :)

dighn
06-25-2002, 12:09 AM
i'm not sure about this one but first of all, by using strcat, you assume ret is a valid null-terminated string. i think when you initialize an array like that its content is random. so you want to make a valid string by saying ret[0] = '\0'; (null terminateing it)

secondly, you cannot return "ret" through the function because ret is a local variable, meaning it's destroyed when the function terminates so if you return its memory address it will not be valid after the function is ended. you will get access violations (seg fault in *nix i think) if you try to access the returned pointer. the simplest way to fix this is by making ret "static" ie static char ret[200]; the static modifier makes sure ret is initialized only once and doesn't go away.

Zoma
06-25-2002, 10:01 AM
Using strcat for every iteration is extremely inefficient. Here is how most (good) programmers I know would probably implement it:


void trims(const char *input, char *output)
{
// Be sure to allocate output like:
// out = new char[strlen(input)+1];
i = 0;
j = 0;

while (input[i] != 0)
{
if (input[i] != ' ')
{
output[j] = input[i];
j++;
}
i++;
}

output[j] = 0;
}


Note that if

btw, Three errors in your original code:
1. Definite error: you can't return ret like you did. It won't exist after the function returns.
2. I think you want to continue if input[i] == ' '. You had !=.
3. Calling strcat on an undefined string (ret) is a bad thing. strcat(a, b) copies string b to string a stating with the first null character in a. Since you don't know what is in ret, it could start copying b anywhere, including in memory.

Strogian
06-25-2002, 02:05 PM
Hmmm ... I'm not sure if I'm right about this, since there were two replys already, and neither of them mentioned this. But, I still don't think that any of this code here will do what you want. When I look at this code, it seems like it will just strip out every space from the string, and return the result. You just want to get rid of leading and trailing spaces, right?

biosx
06-25-2002, 02:52 PM
Look at the strcpy() function in string.h. I am almost positive that strcat() will not achieve what namgor wants (even though I'm not even quite sure what he wants).

Good luck

Zoma
06-25-2002, 03:06 PM
Oops, Strogian is right. Do you wantHere is one way to strip only the first leading and trailing spaces, or all leading and trailing spaces? Since the only the first space is a single case of all spaces, I'll post the solution for all spaces:


void trims(const char *input, char *output)
{
int i, j;
// Be sure to allocate output like:
// out = new char[strlen(input)+1];
i = 0;
j = 0;

while(input[i] == ' ')
{
i++;
}

while (input[i] != 0)
{
output[j] = input[i];

j++;
i++;
}

j--; // added in in case you try this before reading my next post
// and I had to make a different edit, anyways :)

while (output[j] == ' ')
{
j--;
}

output[j+1] = 0;
}


btw, something about what dighn said: He is right in saying that you can't just return a pointer to memory on the stack. While I'm pretty sure using a static variable would work, this is a bad practice. Imagine you have string a with a value of " foo " and string b with a value of " bar ". Now you call a trim function like 'c = trims(a)'. c will now hold "foo". But then you call 'd = trims (b)'. d will now hold the string "bar", but because of how this was implemented, so will c. There are two solutions to this problem (that I'm aware of). One solution is to add a parameter that contains the output. Most of the IO library functions work like this. This is usually a good way to do things, as it requires that memory be allocated by the user, not the function. However, sometimes you might want to return a new variable. To do this, just dynamically allocate the variable in the function. Imagine a function that looks like this:


char* f(int x)
{
char *p;

p = new char[x];

return p;
}

We do something like 'char *x = f()'. Here's what will happen: Inside the function, p will be placed on the stack. However, the x character allocated will be placed on the heap. When the function returns, p will be popped off the stack, but the data it references will remain on the heap. Whatever gets assigned to the function will then point to the data. The reason this isn't used too much is that it is a bit dangerous: you need to be sure to deallocate the memory before your program exits. However, since the function allocated your memory, it isn't obvious to those reading the code. For example:


normal:

void main()
{
int x;
char *s;

x = 10;
s = new char[10];

delete []s;
}

"weird":
void main()
{
int x;
char *s;

x = 10;
s = f(x);

delete []s;
}


These two programs do the same thing, but writing code the second way can sometimes lead in people forgetting to delete s, especially in larger segments of code.

Just my $0.02 :)

Zoma
06-25-2002, 03:47 PM
I think my code was off a bit: add the line 'j--;' before the third while loop and it should work.

namgor
06-25-2002, 05:42 PM
hey guys! i worked around the thing by using the method "strtok", (tokenize by delimiter ' ), anyway, yes, you guys are so careful on the thing, ya, I suppose to cut the space outside of the quote but not inside!

Anyway, thx man!