By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
454,492 Members | 1,652 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 454,492 IT Pros & Developers. It's quick & easy.

Pointer problem.

P: n/a
hi, there,

In the following codes, If I change the varible "string "in main()
to char* string=" this is the test string "; the program will
be crashed. can someone tell me why and how to modify the code so that
I can still use char * string? thanks.

================================
#include <stdio.h>

char *Trim(char *string)
{
char *from, *to;
int spaces = 0;

/* skip leading spaces */
for (from = to = string; *from ==' '; ++from);

for (;*from != '\0'; ++from)
{
if (*from != ' ')
{
if (spaces == 1) *to++ = ' ';
spaces = 0;
*to++ = *from;
}
else spaces = 1;
}
*to = '\0';
return string;

}

int main(void)
{
char string[] = " This is a test of the
string trim ";

printf("Before: \"%s\"\n",string);

string=Trim(string);
printf("After: \"%s\"\n",string);

return 0;

}

================================================== ==========

Nov 15 '05 #1
Share this Question
Share on Google+
4 Replies


P: n/a
ajm
Hi Paul,
In the following codes, If I change the varible "string "in main()
to char* string=" this is the test string "; the program will
be crashed. can someone tell me why and how to modify the code so that
I can still use char * string? thanks.


couple of details first - the return type of Trim is a char * but is
assigned to a variable of (incomplete) type char[] which in any event
is
a string literal so I would suggest that you reserve your variable
"string"
for the input and have a separate variable, "trim_string" (of type char
*) for the output. note that a function does not know if it is passed
a char[] or a char * argument but does know what it is supposed to
return.

next a very minor detail: decide how you wish to return the trimmed
string,
do you want to use a second char ** argument and pass your trim_string
variable
by address (&trim_string) or do you want to pass the trim_string back
as the
return value. The former allows you to communicate errors via return
codes but you could also do this by returning a NULL too.

finally since you are creating a new string (trim_string) you will need
to
malloc some space for it (which requires that the caller free it when
it is no longer needed) - otherwise you are probably going to get a seg
fault or bus error etc. The rest of the trim code (def prt copy etc.)
is probably fine as is (have not studied in detail ;)

hth,
ajm.

Nov 15 '05 #2

P: n/a
Paul a écrit :
hi, there,

In the following codes, If I change the varible "string "in main()
to char* string=" this is the test string "; the program will
be crashed. can someone tell me why and how to modify the code so that
I can still use char * string? thanks.


What about reading the FAQ before posting ?

--
C is a sharp tool
Nov 15 '05 #3

P: n/a
Paul wrote:

hi, there,

In the following codes, If I change the varible "string "in main()
to char* string=" this is the test string "; the program will
be crashed. can someone tell me why
It's undefined behavior to attempt to modify the contents
of an object identified by a string literal.
Modifying most other objects of array type, is OK.
and how to modify the code so that
I can still use char * string? thanks.


char string[] is the right way to do what you want.
char *string is the wrong way to do what you want.

--
pete
Nov 15 '05 #4

P: n/a
ajm wrote:
Hi Paul,
In the following codes, If I change the varible "string "in main()
to char* string=" this is the test string "; the program will
be crashed. can someone tell me why and how to modify the code so that
I can still use char * string? thanks.
couple of details first - the return type of Trim is a char * but is
assigned to a variable of (incomplete) type char[] which in any event
is a string literal


You snipped a bit too much context, namely the parts of the code you are
commenting on. Please don't assume that everyone has seen the post you
are replying to. I'll restore the bits in question as by chance I happen
to have it available. The variable you referred to was in the following:

| int main(void)
| {
| char string[] = " This is a test of the
| string trim ";

string here is *not* an incomplete type, nor is it a string literal. The
C compiler completes the type because is it given an initialiser, the
string literal.

So string is an array of exactly the correct size to hold the string
literal *including* the '\0' that terminates the string.

| printf("Before: \"%s\"\n",string);
|
| string=Trim(string);

You are not allowed to assign to arrays.

| printf("After: \"%s\"\n",string);
|
| return 0;
|
| }

so I would suggest that you reserve your variable
"string"
for the input and have a separate variable, "trim_string" (of type char
*) for the output. note that a function does not know if it is passed
a char[] or a char * argument but does know what it is supposed to
return.
Correct, more or less.
next a very minor detail: decide how you wish to return the trimmed
string,
do you want to use a second char ** argument and pass your trim_string
variable
by address (&trim_string) or do you want to pass the trim_string back
as the
return value. The former allows you to communicate errors via return
codes but you could also do this by returning a NULL too.
You forgot the possibility of modifying the string in place, which
sometimes is an appropriate solution. The problems with modifying the
string in place are:

1) It means you cannot pass a pointer to a string literal, since you are
not allowed to modify string literals (it invokes undefined behaviour
which on some systems shows up as a crash and on others as weird things
happening). This is the reason the OP's program crashed when using "char
*string=" instead of "char string[]=".
2) You cannot enlarge the string.
finally since you are creating a new string (trim_string) you will need
to
malloc some space for it (which requires that the caller free it when
it is no longer needed) - otherwise you are probably going to get a seg
fault or bus error etc. The rest of the trim code (def prt copy etc.)
is probably fine as is (have not studied in detail ;)


One point you missed was that string is a bad name for a variable. At
file scope identifiers starting with str followed by a lower case letter
are reserved if string.h is included, and they are always reserved for
external linkage (even if string.h is not included), so as a matter of
course it is best to just avoid them altogether, including when they are
allowed.
--
Flash Gordon
Living in interesting times.
Although my email address says spam, it is real and I read it.
Nov 15 '05 #5

This discussion thread is closed

Replies have been disabled for this discussion.