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

strings and functions

P: n/a

I am used to Delphi and VB, where functions can return strings. I
recently starting learning C and my findings are that you can have
external functions build strings, but the function cannot return the
string itself, rather, it needs to update a variable that is an array or
points to an array. Correct?

Below is a 'simple' test to work with a string that was created in an
external function (and external file). Based on the result I get (_@),
I know I don't fully "get it" yet. Any help would be appreciated.

//MAIN.C

#include<stdio.h>

main()

{

char *data_from_function;

my_function(data_from_function);

printf("Data results from My Function: %s\n");

}

//MYFUNCTION.C

my_function(char *strData)

{

strData = "HELLO WORLD\n";

}

(Linux 9 i386)

#gcc main.c myfunction.c

#./a.out

Data results from My Function: _@
--
Posted via http://dbforums.com
Nov 13 '05 #1
Share this Question
Share on Google+
12 Replies


P: n/a
c_monty wrote:
I am used to Delphi and VB, where functions can return strings. I
recently starting learning C and my findings are that you can have
external functions build strings, but the function cannot return the
string itself, rather, it needs to update a variable that is an array or
points to an array. Correct?

Below is a 'simple' test to work with a string that was created in an
external function (and external file). Based on the result I get (_@),
I know I don't fully "get it" yet. Any help would be appreciated.

//MAIN.C

#include<stdio.h>
main()
The main() function should have a return type:
int main(void)

{
char *data_from_function;
my_function(data_from_function);
printf("Data results from My Function: %s\n");
Perhaps this should have been:
printf("Data results from my_function: %s\n",
data_from_function); /* you forgot this */ } //MYFUNCTION.C
my_function(char *strData)
{
strData = "HELLO WORLD\n";
}
Pointers are passed by value in C.
If you want to change a pointer, pass the address
or a pointer to the pointer:
void my_function(char * * strData)
{
*strData = "Hellow World\n";
}

or copy the data to the location of the original
array:
void my_other_function(char * strData)
{
strcpy(strdata, "Hello again.\n");
return;
}

int main(void)
{
char string_one[640];
char * string_two;

my_function(&string_two);
my_other_function(string_one);
printf("Results:\n%s\n%s\n",
string_one, string_two);
return 0;
}

(Linux 9 i386)
#gcc main.c myfunction.c
#./a.out

Data results from My Function: _@
--
Posted via http://dbforums.com

--
Thomas Matthews
C Faq: http://www.eskimo.com/~scs/c-faq/top.html
alt.comp.lang.learn.c-c++ faq:
http://www.raos.demon.uk/acllc-c++/faq.html

Nov 13 '05 #2

P: n/a
c_monty <me*********@dbforums.com> writes:
I am used to Delphi and VB, where functions can return strings. I
recently starting learning C and my findings are that you can have
external functions build strings, but the function cannot return the
string itself, rather, it needs to update a variable that is an array or
points to an array. Correct?
Correct.
Below is a 'simple' test to work with a string that was created in an
external function (and external file). Based on the result I get (_@),
I know I don't fully "get it" yet. Any help would be appreciated.

//MAIN.C

#include<stdio.h>

main()
int main (void)
{
char *data_from_function;

my_function(data_from_function);

printf("Data results from My Function: %s\n");
Do you mean `printf("Data results from My Function: %s\n", data_from_function);'?
}
Insert `return 0;' before the closing brace.

//MYFUNCTION.C

my_function(char *strData)
{
strData = "HELLO WORLD\n";
}
`strData' is local to `my_function'. You make `strData' point to a string
literal. Then the function execution ends, and the value of `strData' is
forgotten.

You can return a string literal (more precisely: a pointer to the first
character of string literal) from a function like this:
#include <stdio.h>

const char *my_function (void)
{
return "HELLO WORLD";
}

int main (void)
{
printf ("Data results from My Function: %s\n", my_function ());
return 0;
}
A string literal cannot be modified. If you need to modify the string, you
must copy it to an array:
#include <stdio.h>
#include <string.h>

void my_function (char *const buffer)
{
strcpy (buffer, "HELLO WORLD");
}

int main (void)
{
/* Must be large enough for the string,
including the terminating '\0' character. */
char my_buffer [12];

my_function (my_buffer);

my_buffer [1] = 'A';

printf ("Data results from My Function: %s\n", my_buffer);
return 0;
}

(Linux 9 i386)
<OT>
No such thing. Linux is currently at version 2.4.21; the development branch
is at version 2.6.0-test3.
</OT>
#gcc main.c myfunction.c


Please invoke gcc with at least the following flags: -O -Wall -ansi -pedantic

I recommend `-W' in addition to that.

Martin
Nov 13 '05 #3

P: n/a
c_monty wrote:

I am used to Delphi and VB, where functions can return strings. I
recently starting learning C and my findings are that you can have
external functions build strings, but the function cannot return the
string itself, rather, it needs to update a variable that is an array or
points to an array. Correct?
Pretty much. "C functions can't return strings" is just
a special case of "C functions can't return arrays," because
a string in C is just an array of `char' elements formatted
in a particular way. Recommended reading: Section 6 "Arrays
and Pointers" in the comp.lang.c Frequently Asked Questions
(FAQ) list

http://www.eskimo.com/~scs/C-faq/top.html
Below is a 'simple' test to work with a string that was created in an
external function (and external file). Based on the result I get (_@),
I know I don't fully "get it" yet. Any help would be appreciated.

//MAIN.C

#include<stdio.h>

main()

{

char *data_from_function;

my_function(data_from_function);

printf("Data results from My Function: %s\n");
There are minor solecisms elsewhere, but this is the first
Real Live Error: You've used the "%s" specifier to tell printf()
to output a string, but you haven't told printf() what string
you want it to output! printf() trusts you, looks in the place
where the string's `char*' pointer would have been if you'd
supplied one, gets some kind of garbage, and then there's no
guarantee of what might happen. You've landed yourself in the
perilous land called Undefined Behavior.

}

//MYFUNCTION.C

my_function(char *strData)

{

strData = "HELLO WORLD\n";
Here's the second Real Live Error: You don't understand
that C arguments are passed by value, not by reference.
See Question 4.8 in the FAQ.
}

(Linux 9 i386)

#gcc main.c myfunction.c
Since you're still somewhat shaky in C, it would be a
good idea to crank up gcc's warning levels a bit. I use

gcc -Wall -W -ansi -pedantic -O2 ...

.... except that I omit "-ansi -pedantic" for programs that
can't tolerate such rigidity, and I raise the optimization
level higher than "-O2" when circumstances warrant it.
#./a.out

Data results from My Function: _@


Could have been anything at all, or nothing at all.
Undefined Behavior is, well, undefinable. Folks around
here are fond of saying U.B. might make demons fly out
of your nose. Years ago on this same newsgroup, people
had a wider variety of imaginative U.B. examples, but the
nasal demons seem to have crowded out the creativity.

--
Er*********@sun.com
Nov 13 '05 #4

P: n/a
Thomas Matthews <Th**********************@sbcglobal.net> broke the eternal silence and spoke thus:
void my_function(char * * strData)
{
*strData = "Hellow World\n";
}
This is bad (right?) since strData now points to a constant string that will
vanish when my_function returns...
void my_other_function(char * strData)
{
strcpy(strdata, "Hello again.\n");
return;
}


Also bad, since you don't know in general how much space strData has
associated with it, if any.

If I've done foot-in-mouth again here, I apologize ;)

--
Christopher Benson-Manica | Jumonji giri, for honour.
ataru(at)cyberspace.org |
Nov 13 '05 #5

P: n/a


On 8/22/2003 1:31 PM, pete wrote:
c_monty wrote:
<snip>
char *my_function(char *strData)
{
strData = malloc(sizeof "HELLO WORLD\n");
if (strData) {
strcpy(strData, "HELLO WORLD\n");
}
return strData;
}

Why would you have "my_function" take an argument in this case? Wouldn't you
really write this as:

char *my_function()
{
char *strData;
strData = malloc(sizeof "HELLO WORLD\n");
if (strData) {
strcpy(strData, "HELLO WORLD\n");
}
return strData;
}

so that instead of being called as:
data_from_function = my_function(data_from_function);


it can be called as:

data_from_function = my_function();

Regards,

Ed.
Nov 13 '05 #6

P: n/a
On Fri, 22 Aug 2003 13:48:54 -0400, c_monty wrote:

I am used to Delphi and VB, where functions can return strings. I
recently starting learning C and my findings are that you can have
external functions build strings, but the function cannot return the
string itself, rather, it needs to update a variable that is an array or
points to an array. Correct?
These other environments are likely returning pointers (Java calls them
references) as well. C permits pointer arthmetic which gives C it's
razor's edge. Be careful.
my_function(data_from_function);

printf("Data results from My Function: %s\n");


You just forgot to add the string you want to print:

printf("Data results from My Function: %s\n", data_from_function);

In C the way to "return strings" is to return a pointer to an array
of characters:

char *
tostr(void)
{
return "hello";
}

Mike
Nov 13 '05 #7

P: n/a
Ed Morton wrote:

On 8/22/2003 1:31 PM, pete wrote:
c_monty wrote:
<snip>
char *my_function(char *strData)
{
strData = malloc(sizeof "HELLO WORLD\n");
if (strData) {
strcpy(strData, "HELLO WORLD\n");
}
return strData;
}


Why would you have "my_function" take an argument in this case?


It's a vestigial feature from the original post.
Wouldn't you really write this as:

char *my_function()
{
char *strData;
strData = malloc(sizeof "HELLO WORLD\n");
if (strData) {
strcpy(strData, "HELLO WORLD\n");
}
return strData;
}

so that instead of being called as:
data_from_function = my_function(data_from_function);


it can be called as:

data_from_function = my_function();


Yes, I think that's better.

--
pete
Nov 13 '05 #8

P: n/a
at***@nospam.cyberspace.org wrote:

Thomas Matthews <Th**********************@sbcglobal.net>
broke the eternal silence and spoke thus:
void my_function(char * * strData)
{
*strData = "Hellow World\n";
}
This is bad (right?) since strData now points to a
constant string that will vanish when my_function returns...


No. Those kinds of strings persist.
The strData pointer itself, will disappear,
but the desired side effect will happen.
The external pointer that *strData points to,
will be pointed at the string.
void my_other_function(char * strData)
{
strcpy(strdata, "Hello again.\n");
return;
}


Also bad, since you don't know in general how much space strData has
associated with it, if any.


That particular criticism is valid.

This works:

#include <stdio.h>

void my_function(char * * strData)
{
*strData = "Hellow World\n";
}

int main(void)
{
char *data_from_function;

my_function(&data_from_function);
printf("Data results from My Function: %s\n",
data_from_function);
return 0;
}

--
pete
Nov 13 '05 #9

P: n/a
pete <pf*****@mindspring.com> spoke thus:
> void my_function(char * * strData)
> {
> *strData = "Hellow World\n";
> }
This is bad (right?) since strData now points to a
constant string that will vanish when my_function returns...

No. Those kinds of strings persist.
The strData pointer itself, will disappear,
but the desired side effect will happen.
The external pointer that *strData points to,
will be pointed at the string.


So, since it's a string literal, it still ends up in the static section of
memory or something? The function still doesn't work if strData happens to be
NULL... And even if it does work, you can't do something like
*strData[3]='a', right, since the string is literal?

--
Christopher Benson-Manica | Jumonji giri, for honour.
ataru(at)cyberspace.org |
Nov 13 '05 #10

P: n/a
at***@nospam.cyberspace.org wrote:
Thomas Matthews <Th**********************@sbcglobal.net> broke the eternal silence and spoke thus:

void my_function(char * * strData)
{
*strData = "Hellow World\n";
}

This is bad (right?) since strData now points to a constant string that will
vanish when my_function returns...


No, the location of the literal will persist.
void my_other_function(char * strData)
{
strcpy(strdata, "Hello again.\n");
return;
}

Also bad, since you don't know in general how much space strData has
associated with it, if any.

If I've done foot-in-mouth again here, I apologize ;)


Yes, this is also bad, but it is another alternative.
Welcome to the problem with C arrays.

--
Thomas Matthews
C Faq: http://www.eskimo.com/~scs/c-faq/top.html
alt.comp.lang.learn.c-c++ faq:
http://www.raos.demon.uk/acllc-c++/faq.html

Nov 13 '05 #11

P: n/a
ark

"pete" <pf*****@mindspring.com> wrote in message
news:3F***********@mindspring.com...
Christopher Benson-Manica wrote:
Something like that.

<snip>
The function still doesn't work if strData happens to be
NULL... And even if it does work, you can't do something like
*strData[3]='a', right, since the string is literal?


Yes, you can't do something like that, because of that.

--
pete


Being a practitioner, cannot remember what the std says, but I've seen
different things. A string literal can be a const (in which case, the linker
can collect identical strings in one) or not. I've seen it also as a
compiler switch.
arkk at macroexpressions.com
Nov 13 '05 #12

P: n/a
ark wrote:

"pete" <pf*****@mindspring.com> wrote in message
news:3F***********@mindspring.com...
Christopher Benson-Manica wrote:
Something like that.
<snip>
The function still doesn't work if strData happens to be
NULL... And even if it does work, you can't do something like
*strData[3]='a', right, since the string is literal?


Yes, you can't do something like that, because of that.

Being a practitioner, cannot remember what the std says,
http://anubis.dkuug.dk/JTC1/SC22/WG14/www/docs/n869/

It says that attempts at string literal modification,
result in undefined behavior.
When I said "you can't do that",
I meant "Doing that, isn't sanctioned by the standard",
but ..., you can attempt a lot of things that wind up working
on your system, which in fact are not sanctioned by the standard.
People frequently post code which invokes undefined behavior,
while they insist that the code is correct because it
produces the desired result on their system.

but I've seen different things.
A string literal can be a const (in which case, the linker
can collect identical strings in one) or not.
The standard says that that is allowed.
I've seen it also as a compiler switch.
arkk at macroexpressions.com


--
pete
Nov 13 '05 #13

This discussion thread is closed

Replies have been disabled for this discussion.